第十三讲 ASP.NET中的错误处理和程序优化
摘要
。错误类型以及处理方式
。提高数据访问性能
。服务器控件的使用
。缓存的使用
。提高性能的实用技巧
*错误类型以及处理方式
1、错误的类型
。分析程序错误
-语法错误:语法有问题
-逻辑错误:除0错误,类型不匹配,不正确输出,使用不正确的对象,处理无效的数据。
。编译错误:使用了不能被语言编译器识别,但ASP.NET能识别的关键字或语句时发生的错误
。运行时错误
。配置错误:Web.config文件出错
2、错语的处理
。使用验证控件
。编程处理
-校验语句
-try...catch...finally
-Page_Error
-Application_Error
。在应用程序配置文件中,为应用程序执行的声明性错误处理。
校验(checked)和非校验(unchecked)语句
*异常类:Exception
。所有异常对象的基类
。属性:
-HelpLink:到一个文件的链接,该文件包含关于错误的更详细的信息
-InnerException:一个内部异常的引用。如果一个异常被捕获,并被传递给另外一个异常处理程序,则该属性返回到第一个异常的引用。
-Message:描述异常的引用
-Source:一个字符串,其中包含引起错误的对象的名称。
-StackTrace:返回一个指出错误原因的栈跟踪
-TrageSite:引起错误的方法。
*Page对象的Error事件
。使用模板
void Page_Error(object sender,EventArgs e)
{
Response.Write("发生错误:"+Server.GetLastError().ToString());
Server.ClearError();
}
*Application对象的Error事件
。应用程序中任何页面抛出异常都会调用
。在global.asax中
。形式为:
void Application_Error(object sender,EventArgs e)
{
......
}
*利用配置文件处理错误
。ASP.NET同以前的ASP一样,当服务器上发生了一个运行时间或编译时间错误时,就全生成一个html错误页面。但是与ASP不同,ASP.NET格外
关注的是:要确保在默认状态下,不会因为这个错误的发生而泄露“安全”信息。
。
<system.web>
<customErrors defaultRedirect="url" mode="RemoteOnly">
<error statusCode="code" redirect="url"></error>
</customErrors>
<?system.web>
*提高数据访问性能
使用最佳的Data Provider:
-System.Data.SqlClient
-System.Data.OracleClient
-System.Data.OleDb
-System.Data.Odbc
。所有Provider的编程模型相同
-但是性能方面存在明显差异
。建议:使用最佳Provider
-在访问MSDE/SQL时始终使用SqlClient
-在访问Oracle时始终使用OracleClient
*DataReaders和DataSets
.DataReader
-对查询的结果提供了单向读取的操作
-轻量快速-但在Reader为关闭之前始终处于连接状态
.DataSet
-非链接的数据访问方式
-内部使用DataReader用于获取数据
-在完成DataSet的获取后会自动关闭DataReader
.如何选择?
-依赖于您的应用
-一般情况下,读取大量数据,对返回数据不做大量处理用sqlDataReader,对返回数据大理处理用DataSet比较合适。
.ExecuteNonQuery和ExecuteScalar
.ExecuteNonQuery
-对数据的更新不需要返回结果集
-由于不返回结果集可省掉网络数据传输。它仅仅返回受影响的行数。如果只需要新数据用ExecuteNonQuery性能的开销比较少。
.ExecuteScalar
-它只返回结果集中第一行的第一列。使用ExecuteScalar方法从数据库中检索单个值(例如ID号)。
-与使用ExecuteReader方法,返回的数据执行生成单个值所需的操作相比,此操作需要的代码较少。
.如何选择?
-只需要更新数据用ExecuteNonQuery.单个值的查询使用ExecuteScalar
*数据的绑定DataBinder
。一般的绑定方法<%#DataBinder.Eval(Container.DataItem,"字段名")%>用DataBinder.Eval绑定不必关心数据来源(DataRead或DataSet)
。不必关心数据的类型Eval会把这个数据对象转换为一个字符串。在底层绑定做了很多工作,使用了反射性能。正因为使用方便了,但却影响
了数据性能。
。直接转换成DataRowView的话,将会给性能带画很大提升:
<@%((DataRowView)Container.DataItem)["字段名"]%>
*连接池
。ADO.NEt拥有内置的连接池
-自动缓存/重新使用连接
-不必为此编写任何代码
。代码建议:
-“在后期打开代码中的连接,然后在早期将其关闭”
-切勿长时间保持连接状态
-完成后应立即显示地关闭数据库连接,以将其返回至池中。
。优化提示:
-不同的连接字符串可以生成多个不同的连接池
-在Web.Config中存储单个连接字符串
-使用ConfigurationManager.ConnectionStrings["名称"].ConnectionString,以在运行时采用编程形式对其进行访问
。始终应明确关闭数据连接,避免连接泄漏
-否则连接将在下一次垃圾收集之胶保持打开状态
-泄露连接会显著降低性能。
*使用存储过程
。建议将SPROC用于数据存取
-通过使用数据库事务处理避免出现分存事务成本
-有助于防止SQL注入攻击
-有助于消除应用与数据库反复调用的成本
。有趣的提示:
-可以通过企业管理器来关闭动态SQL支持,以强制使用SPROC
*服务器控件的使用
。提供了清晰的编程模型(重用,简洁,宜用)
-创建ASP.NET页面所倡导的模式
。对性能优化而言有两点需要注意工:
-ViewState
-控件数量
*ViewState管理
。ASP.NET Controls能够维护页面Control元素的状态
-状态以"ViewState hidden filed"进行传递
。负面影响
-增加网络负荷(both on render and postback)
-额外的服务器性能消耗(serialize values to/from viewstate)
。Viewstate灵活性:
-页面级(Can disable viewstateentirely for a page)
-控件级(Can disable viewstateusage on a per control basis)
。建议:
-认真审核该功能的使用
-若不使用PostBack功能,请在页面级蔽ViewState
-PostBack时每次都重新生成控件,请对控件级的ViewState屏蔽
-使用<%@ Page Trace="true" %>跟踪ViewState的大小
*有关ViewState管理提示
。如果您希望更明确的限制ViewState的使用,可将ASP.NET配置为默认情况下处于关闭状态
。Machine.config
<configuration>
<System.Web>
<Page enableViewState="false" />
</System.Web>
</configuration>
。之后需要ViewState的页将在页面指令中手动对其进行设置:
<%@ Page EnableViewState="true" %>
*生成的控件数量
。页面上的每个服务器控件的生成都存在固定的成本。
-每个控件的成本通常可以忽略不计
。复合控件有进可以屏蔽使用的控件数量,尽管会出现以下情况
-聚集成本有时可以累加
-打开ASP.NET Trace即可查看实际计数
*使用缓存进行程序优化
1、什么是缓存技术?
缓存是计算机快速地再次获得数据的方式。
2、缓存原理
将经常访问地数据存储到计算机可以更快,更容易地读取地位置。
4、什么时候用缓存?
*使用缓存的情况
。缓存那些经常被访问、并且变化不大的数据
。缓存整个应用程序都要使用的设置或对象(但这些设置和对象必段在其生存期内不变化)
*不应该使用缓存的情况
。不要缓存个人信息,以防止别人盗用。
。不要缓存包含时间的页面
。不要缓存用户随时都会修改的对象,如购物车。
5、如何使用缓存?
。ASP.NET有两种用于Web应用的缓存技术:输出缓存和数据缓存。
-输出缓存指:把一次请求所产生的动态输出保存于内存中。
-数据缓存指:按照一定的策略把事先不确定的对象保存于内存中。
。输出缓存的使用
-使用@OutputCache指令
-例如(添加在页头)
<%@ OutputCache Duration="10" VaryByParam="None" %>
数据缓存
。ASP.NET提供了一个相当出色的缓存引擎机制,它允许页面保存和索引HTTP请求所要求的各种各样的对象。ASP.NET的缓存对各个应用来说是
私有的,是存储各种对象的存储器。缓存的生存周期取决于应用的生存周期,也就是说,当应用重新启动时,缓存实际上也已重建。
。数据缓存
-使用(类似于Session变量的使用)
Cache["UserName"]="MiMi";
Response.Write(Cache("UserName"));
-注意不能通过下标访问缓存中的变量,如Respose.Write(Cache[0]);j 错误的。
-缓存的删除
Cache.Remove("UserName");
。使用缓存依存关系
-缓存变量的添加
。Cache.Add();
。Cache.Insert();
它们功能相同,但Insert更加灵活一些
-Insert(key,value,dependencies,absoluteExpiration,slidingExpiration,priority,priorityDecay,onRemoveCallBack)
。缓存替换策略
1、“腐烂搜索”(Scavenging)
。当内郹变得比较紧张时,缓存机制会找出最不常用和最不重要的对象,把它从内在中移出,以减轻系统压力。
2、“到期控制”(Expiration)
。编程者可以指定缓存对象的生存周期,这种指定的时间可以是绝对的也可以是相对的。
3、“文件和键值依赖”
。从外部文件或者是其它缓存键值是否改变,来决定本身键值是否有效。
*提高性能的实用技巧
。不要使用不必要的Session,和ASP中一样,在不必要的时候不要使用Session
。不使用不必要的server Control
。不使用不必要的ViewState
。不要用Exception控制程序流程
。禁用VB和Jscript动态数据类型
。使用存储过程完成数据访问
。只读数据访问不要使用DataSet
。关闭ASP.NET和Debug模式
。使用ASP.NET Output Cache缓存数据
。尽量用SQL返回DataGrid需要绑定的DataSet,尽量不要对DataSet进行二次加工,特别不要对DataSet进行大量删除,实践证明这样很慢。不如复制部分数据。
。尽量把查询数据的数据库操作次数压缩到最少,尽量1-2次数据库操作就可以完成。
。注意优数据库查询操作。
。不要在页面加载时默认选择全部数据,尽管可以方便后续操作,但用户会以为“还没有操作就这么慢”
。建议尽量用比较高效的SQL代替后续复杂的DataSet二次加工。
。仅在需要的时候打开数据库连接
。一旦数据库操作完毕,一定关闭连接
。在关闭连接时记得删除临时对象
。在关闭连接前,确保关闭任何用户定义事务
。显示非交互性数据,使用SQLDataReader可以获得最佳性能。
。注意共享那些经过复杂处理或漫长查询才得到的数据
。在页面跳转时记得终止当前页面的处理。
。有大量连接的字符串操作不要使用+,改用StringBuilder