要提升ASP.NET应用程序的性能,最简单、最有效的方式就是使用内建的缓存引擎。虽然也能构建自己的缓存,但由于缓存引擎已提供了如此多的功能,所以完全不必如此麻烦。在很大程度上,ASP.NET开发者在Web应用程序中,能将缓存引擎的功能直接包装到自己的数据表示及访问类中。如本文所述,整个过程其实非常简单。
ASP.NET缓存引擎类型
整页输出缓存是在一个页被***请求时,将整个页呈现好的HTML内容缓存下来。后续请求将直接取用缓存拷贝。
部分缓存是指缓存一部分HTML内容,这类似一个Web用户控件的输出。之所以叫这样的一个名字,是因为我们一般说“将一部分HTML提交给一个页”。
数据缓存关注的是单独的变量或数据项的缓存。它在比以上两种缓存类型都要低的一个级别上工作。
整页输出缓存
整页输出缓存是最简单的缓存类型,它只要求为准备缓存的页添加一个预处理指令 OutputCache。使用这种缓存,就不必重新处理一个页的Init, Load,PreRender,Render以及Unload事件。假如那些事件要访问像数据库那样的一个后端系统,那么节省的时间将是非常可观的。ASP.NET缓存一个页的几个变体,并将每个页都与后续请求相关联。
部分缓存
部分缓存允许只缓存部分HTML,它的效率很高,因为一个页中经常变化的部分可与那些不经常变化部分的部分合并到一起,同时仍能从缓存中检索静态的部分。一个实例是将“部分缓存”应用于需要调用XML Web服务的Web用户控件。这样可获得很高的效率,因为它避免了你的网站与Web服务过度紧密地耦合,同时还能显著提升性能。
要使用部分缓存,同样可在HTML页的顶部放置一条OutputCache预处理指令。但这一次,我们准备把它放到Web用户控件的ASCX页中。注意使用部分缓存时, Location和VaryByHeader属性将不再支持,但新增了对VaryByControl属性的支持。
使用VaryByControl属性,可用一个由分号分隔的列表来指定用户控件的一个或多个属性。可为属性值的每一种组合来创建缓存的版本。例如,假定你的用户控件揭示出一个自定义的 State属性,它控制着要显示用户控件的哪些元素。使用以下预处理指令,可针对 State的每个值来缓存控件所具体呈现的一个版本:
<%@ OutputCache Duration="300" VaryByControl="State" %>
但在缓存Web用户控件时,记住ASP.NET运行库会直接用缓存的HTML来替换实际控件,忽略平常会发生的任何控件处理。这暗示着在网页中执行的代码不能程序化地操纵一个缓存的用户控件或者它的任何属性。换言之,Web用户控件必须能完全自主,并能通过它的 Load和Init事件来初始化自己,以便有效地缓存。
也可声明性地完成部分缓存,方法是使用一个属性而不是使用OutputCache预处理指令。在代码隐藏文件中, PartialCaching属性可放在从UserControl派生的一个类中,使ASP.NET运行库能够读取它,并相应地缓存呈现好的HTML。例如,以下来自代码隐藏类的声明能根据查询字符串中的 id值,将Web用户控件缓存5分钟。
数据缓存
ASP.NET缓存引擎支持的***一种缓存类型是“数据缓存”。根据定义,它的工作级别要低于整页输出缓存和部分缓存。假如几个网页都要使用相同的数据(例如一个产品列表),但要以不同方式来显示这些数据,就可考虑使用这种缓存。当然,数据缓存之所以具有性能优势,是因为减少了对后端数据库的调用次数。
为了在缓存中添加一个项,需使用Page或UserControl类的Cache属性,因为这两个类最终都是从Control类派生的。 Cache属性揭示出了System.Web.Caching.Cache对象,利用它可将数据当作键和值的一个组合来存储。使用该属性,开发者可编写代码来填充一个项,并把它放到缓存中;如果该项已经存在,就直接将其从缓存中取出。如以下C#代码所示。
DataTable dt = null; if (this.Cache["Products"] == null) { // Go get the data from the database this.Cache.Insert("Products", dt, null, _ DateTime.Now.AddHours(6), TimeSpan.Zero); } else { dt = this.Cache["Products"] As DataTable; }
上例首先检查具有Products键的项是否在缓存中。如果不在,就从后端数据库检索一个ADO.NET DataTable,并使用Insert方法把它放到缓存中。本例使用的是 Insert的一个重载版本,它允许为缓存对象指定一个绝对过期时间(6小时),而不是指定一个周期性的过期。相反,如果缓存中已经有这个项,就将其取回,并使用 As表达式,将其强制转换回一个DataTable。
对ADO.NET检索到的数据进行缓存时,注意既可像上例那样缓存DataTable对象,也可缓存整个 DataSet对象,因为两种对象都同任何数据源完全地断开,不会保持数据库连接。对数据读取器(比如 SqlDataReader)进行缓存似乎更好一些,因为它们只使用一次(它们是“只进”的读取器),而且在打开的情况下将一直占据一个数据库连接。
ASP.NET缓存引擎强大的灵活性和功能使其成为创建高性能ASP.NET应用程序时最重要的特性之一。根据本文提供的基本信息,你可在自己的应用程序轻松引入缓存引擎功能。
【编辑推荐】