正文

(翻译)ASP.NET2.0中的输出缓存2007-10-21 14:46:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/goalbell/30270.html

分享到:


介绍:

   采用缓存是改善web应用程序执行能力(性能)最可靠的方法之一。缓存在一个快速可存取的位置中采用一些昂贵的操作以及存储它的结果。ASP.NET版本1.0介绍了两种口味的缓存:

     1、输出缓存---缓存整个提供一个ASP.NET web页面的组成或者特定期限的用户控件。

     2、数据缓存---用来在web服务器内存中存储对象的一个以编程可存取, 在内存数据高速缓存。

获得更多关于ASP.NET 1.x的缓存可兼容性的深入讨论,参考Scott McFarland的ASP.NET的缓存技术以及Steve Smith的ASP.NET 缓存:技术与最佳实践的文章。

在ASP.NET 2.0中,缓存系统已经被扩展到包括SQL cache dependencies,cache profiles,以及回调缓存(post-cache)替换输出缓存。ASP.NET快速开始的Caching for Performance的一段提供ASP.NET 2.0的缓存选项的很好地概况。这篇文章探索ASP.NET中的输出缓存,以一个输出缓存的概况和随后进行仔细审视创建页开始,该创建页包括缓存和非缓存两者的组成,使用片段缓存(fragment caching)和回调缓存(post-cache)替换技术。继续读下去可以学习得更多!

输出缓存的概况

输出缓存通过缓存提供ASP.NET web页面的组成以及服务这项内容,而不是重新绘制页面来改善ASP.NET应用程序的性能。举个例子,想象一个你拥有一个ASP.NET页面,用来显示数据库Employees表的记录,列出当前employee的信息。没有缓存,每一次该页面存取一个连接来连接数据库,表被查询,以及结果返回到请求的客户端。但是employee信息每隔多久变化呢?可能不超过每日一次或使,使得许多这些对数据库的请求多余的。有了输出缓存,当该页面第一次被访问绘制的HTML将会以特定的期限被缓存下来。在这段时间期间,如果用户请求该页面,该缓存组成会被返回,从而节省数据库访问以及页面绘制的费用。

总而言之那就是输出缓存!为了实现输出缓存,简单地添加<% @OutputCahe %>指向你的页面顶部,象这样:

<%@ Page ... %>
<%@ OutputCache Duration="duration" VaryByParam="paramList" %>

duration是其中有多少秒绘制组成保留在缓存中。paramList是参数列表,其值更改缓存。举个例子,如果显示employees的页面只是显示那些在某部门的employees,通过一个querystring 参数作为决定,然后我们想通过该参数来更改缓存。为了更准确,想象一下当访问象ShowEmployees.aspx?DepartmentID=departmentID,我们employee页面显示一个某部门的employees。如果缓存不受任何参数影响的话,然后当一个用户访问ShowEmployees.aspx?DepartmentID=Sales,在sales部门的employees会被返回并且组成被缓存下来。如果一个用户在该缓存期限里面访问ShowEmployees.aspx?DepartmentID=IT,他们仍然会看到缓存销售人员而不是IT人员。

为了修正这个,我们简单地需要指示输出缓存引擎通过DepartmentID参数来更改它的缓存:

<%@ OutputCache Duration="duration" VaryByParam="DepartmentID" %>

为了通过所有参数更改,使用一个星号(*);为了通过无参数更改,使用“None"。

输出缓存的奥秘

当输出缓存很容易实现,只是添加<%@ OutpuCache %>指向-有一些值得注意的奥妙。正如前面所讨论,适当地更改缓存是重要的,以至正确的缓存版本被服务基于输入参数的值。除了VaryByParam,还有额外的VaryByX选项应该被考虑。举个例子,你可能会通过浏览器来更改缓存,既然antequated浏览器以HTML 3.2标签被绘制。而如果你拥有一个能操多种语言的站点,你会想通过你使用何种参数来更改缓存,决定显示的语言。参考ASP.NET 缓存:技术与最佳实践的细节关于通过HTTP头或者定制的值更改缓存。

观察输出缓存的性能

输出缓存在ASP.NET中作为HTTP Module被实现的,尤其System.Web.Caching命名空间里面的OutputCacheModule类。一个HTTP Module监听引发在生命周期请求的事件以及当某一特定事件引发能够执行代码。该OutputCacheModule HTTP Module订阅ResolveRequestCache和UpdateRequestCache的事件。在ResolveRequestCache事件,该module决定如果该文件正在被请求加入输出缓存以及,如果这样的话,有一个传回的缓存版本。如果没有缓存版本的话,页面通常被绘制。在另一方面当UpdateRequestCache事件引发,该module会缓存该绘制输出(如果页面被设置来支持输出缓存)。下面的顺序图通过OutputCacheModule module简单化该任务的执行,但突出了整体工作流程。


如果你想一个页面输出缓存到期,在该特定期限到达之前,有两个选择。你可以编程的方式通过调用Response.RemoveOutputCacheItem(path)方法来为某个页面去除输出缓存内容。path是虚拟绝对路径。你也可以与该输出缓存联系外部依赖,正如在Caching Page Output with Cache Key Dependencies讨论一样。这包括为一个页面配合SQL Cache Dependencies到输出缓存的能力;查看ASP.NET2.0快速开始的SQL Cache Invalidation的一段。以其来获得更多的信息。

输出缓存只是其中一页的一部分
 
输出缓存默认缓存整个页面的绘制组成。很多時候,虽然我们希望保持页面动态的某些部门。我们可能想缓存昂贵的,不改变的项-数据的显示,例如-保持广告,用户指定的数据,或者其他经常变化的信息"活"。在ASP.NET 1.x中这可能只是通过片段缓存(fragment caching)来完成,这允许你说,“保持此页面动态除了这些部门。“ASP.NET2.0支持片段缓存(fragment caching),但还介绍一个回调缓存(post-cache)替代模式,即允许你说相反的一面:“保持此页面缓存除了这些动态部门。”让我们首先观察片段缓存(fragment caching)以及然后转向我们的注意力到回调缓存替代部份。
 
控件缓存是通过创建一个没有输出缓存指向,而使用一个用来输出缓存的用户控件的页面而工作的。在此文章最后下载包括一个简单的例子-有一个命名为CachedUserControl.ascx的用户控件,显示数据表的记录,伴随着日期/时间在哪个数据被检索。这个用户控件包含一个<%@OutputCache %>指令:
<%@ Control ... %>
<%@ OutputCache Duration="15" VaryByParam="None" %>

... markup that displays records from a database table ...
 
包含该用户控件的页面不含有<% @OutputCache %>指令。每一次该页面被访问重新呈现的结果,但该用户控件仅仅重新呈现(以及因此只是找到数据库)至多每15秒一次。
 
下面截图显示当它第一次被访问时的页面。指示页面的日期/时间以及用户控件是相同的。几秒之后重新访问该页面,然而,显示该用户控件正在被缓存-该页面的日期/时间上升了几秒,但是该用户控件的时间来自当它第一次被访问的时候(没有变化)。
 

 
 
检查一下文章最后的可用下载以及在该例子中使用的用户控件。还查看http://support.microsoft.com/kb/308378(How to Perform Fragment Caching in ASP.NET by Using Visual C#.NET),一步一步观看片段缓存的例子。
 
通过回调缓存替换使一个页面的缓存部份变得动态
 
ASP.NET2.0添加另外一个技术来组合缓存和动态内容-回调缓存替换。正如相同的意味着,这个方法采取一个页面使用输出缓存以及允许你在被缓存的内容中使到"活"的替换。有两种方法,回调缓存可以被应用:
 
   1、Declaratively-使用Substitution 控件指定页面的动态部份。你需要创建一个通过这些控件会被调用的方法,为了获得它们的呈现组成。
   2、Programmatically-Response.WriteSubstitution(callback)方法以编程的方式注入一个回应替代块。该callback参数是一个委托给一个方法,
该方法会被调用来获得接收的组成。
 
为了使用该declarative案例,简单地添加一个Substitution控件到你的输出缓存页面,你希望注入动态数据的位置。
<%@ Page ... %>
<%@ OutputCache Duration="duration" VaryByParam="paramList" %>
...
   <asp:Substitution ID="id" runat="server" MethodName="method" />
...
 
MethodName(string)属性指出在该页面的code-behind类的静态方法,该方法必须接受一个HttpContext对象并且返回接收的字符串。想象一下我们拥有包含缓存数据的页面,但我们想包含动态的消息(或者一个广告)。我们可能添加一个Substitution控件到该页面,我们希望消息被呈现的位置:
 
<asp:Substitution ID="DynamicMessage" runat="server" MethodName="GetMessage" />
 
 
这儿我们指定GetMessage作为方法名。因此,我们需要创建一个静态方法到该页面的code-behind类,并且GetMessage返回一个字符串:
'VB
Private Shared Function GetMessage(ByVal context As HttpContext) As String
   Return "This ad brought to you by the time " & DateTime.Now.ToString()
End Function


// C#
private static string GetMessage(HttpContext context)
{
   return "This ad brought to you by the time " + DateTime.Now.ToString();
}
 
当此页面被访问时,正常情况下,它的内容会被缓存下来。在随后的访问,尽管,当页面仍然被缓存,OutputCacheModule会调用GetMessage方法以及设置它的输出在合适的页面区段中。
 
结论:
 
ASP.NET的输出缓存特点允许一个页面或者用户控件的整个HTML输出被缓存,从而帮助提高应用程序的整体表现。输出缓存的逻辑通过HTTP handler来处理的,OutputCacheModule。很多时候,一个页面需要使到一些部分被缓存,当离开其他的动态时候。ASP.NET2.0提供两种机制去完成这个片段缓存和回调缓存替换。伴随片段缓存,该页面通常剩下来,动态页面没有输出缓存。那些页面的区段应该被缓存,然而,需要配置使用输出缓存的用户控件来实现。使用回调缓存替换的其他途径,页面被配置使用输出缓存。Substitution控件能够添加页面来指示区域,每个页面的访问不论该页面是否被缓存,内容应该都被动态地产生。回调缓存替换对于ASP.NET2.0来讲是全新的。
 
祝编程愉快!
 
By Scott Mitchell
 

P.S.翻译文章引用地址:http://aspnet.4guysfromrolla.com/articles/121306-1.aspx

阅读(2507) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册