ASP.NET 2.0中的Output Caching

系统 1181 0

本文英文原版以及代码下载:
http://aspnet.4guysfromrolla.com/articles/121306-1.aspx

ASP.NET 2.0中的Output Caching

导言:

要想提升web application的性能的话,使用caching技术是肯定能实现的.Caching利用一些操作将结果存储在一个本地可以快速访问的地方.在ASP.NET version 1.0里引入了2种技术:

.Output Caching -在特定的时间段内,将一个ASP.NET web页面或User Control的完整代码数据进行缓存.

.Data Caching—将objects对象存储在web server的内存里,这些存储在内存里的数据可以通过编程来访问.

关于ASP.NET 1.x缓存技术的更深入的探讨,可参阅Scott McFarland的文章《Caching with ASP.NET》,以及Steve Smith的《ASP.NET Caching: Techniques and Best Practices》.

在ASP.NET 2.0,缓存系统已经扩展到包含SQL cache dependencies, cache profiles, 以及post-cache substitution.在ASP.NET 2.0 QuickStarts( http://quickstarts.asp.net/QuickStartv20/aspnet )的“Caching for Performance”部分,对ASP.NET 2.0里的caching进行了很好的综述.本文探究ASP.NET 2.0中的output caching,最开始我们将对output caching进行综述,接着我们将详细的考察如何利用fragment caching和post-cache substitution技术来创建一个包含cached 和 non-cached代码的页面.

Output Caching综述

Output caching是这样提升ASP.NET应用程序的性能的,它将一个ASP.NET web页面的代码缓存起来,而不是对页面进行重新绘制.打个比方,比如有一个ASP.NET页面,该页面将一个名为Employees的数据库的记录显示出来, 顾名思义,该表存储的是当前员工的信息.如果不进行缓存的话,每当访问该页面的时候,都会造成对数据库的连接,对表的请求,最后将结果返回给请求客户端.但是,雇员信息隔多久才会有更改的情况呢?可能一天,那么对数据库的频繁请求也太过了吧.如果利用output caching的话,在初次对页面的访问时,对要返回的HTML将在一定的时间进行缓存.在这个时间内,如果某个用户请求该页面,就将缓存数据返回。这样便节省了数据库访问和页面绘制的系统开销.

这就是一个简单的output caching。要贯彻它的话,只需要简单的在页面顶部添加声明
<% @OutputCache %> ,像这样:

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

其中,duration就是要缓存的秒数. paramList是一系列的参数,这些参数的值将对缓存产生影响.打个比方,如果某个页面只需要将某个特定部门的员工信息显示出来,而到底是哪个部门则由查询参数来决定,在这种情况下,我们就可以利用该参数来对缓存施加影响.具体来说,比如我们想通过访问ShowEmployees.aspx?DepartmentID=departmentID这个页面来展示某个部门的员工,如果没有通过参数对缓存施加影响,当一个用户访问 ShowEmployees.aspx?DepartmentID=Sales页面时,那么将返回Sales部门的员工信息,并对页面进行缓存,而如果在缓存期间恰好有另一个用户访问ShowEmployees.aspx?DepartmentID=IT页面,那么他将会看到缓存的sales部门而不是IT部门的员工信息.

为解决这个问题,我们仅仅需要通过参数DepartmentID来使output cache引擎来实现多样化缓存,如下:

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

要通过所有的参数来实现缓存多样化,可以使用星号(*);如果不使用参数,使用"None".

Output Caching技巧

虽然实现output caching很容易—仅仅添加<%@ OutputCache %>标记,不过仍然有一些技巧值得我们关注.正如前面探讨的,对缓存实施多样化很重要,这样我们便可以根据输入参数的值进行恰当的缓存.除了VaryByParam,还可以考虑使用VaryByX操作。比如,我们可以根据浏览器的不同实施不同的缓存,还有如果有一个多语言版本的网站,你可以根据使用语言情况的不同来进行不同的缓存.关于根据HTTP headers 或 custom values的不同来进行不同缓存的具体细节可参阅文章《ASP.NET Caching: Techniques and Best Practices》

考察Ouptut Caching的内部机制

在ASP.NET里,Output caching是作为一个HTTP Module来贯彻的.具体来说就是 System.Web.Caching命名空间里的OutputCacheModule类.一个HTTP Module对一个request 的生命周期内的事件进行监听,如果触发了某个具体的事件就执行代码.该OutputCacheModule HTTP Module对应ResolveRequestCache 和 UpdateRequestCache.

在ResolveRequestCache事件里,该module判断是否有output caching请求,如果是,则返回一个缓存版本,如果没有所需要的缓存版本的话就呈现正常页面.在事件结束时又触发 UpdateRequestCache事件,该module将对rendered output进行缓存(如果该页面被设置为支持output caching的话).下图对OutputCacheModule module要执行的这些作业进行了简单的描述,虽然简单了点,但概括了总体的流程.

ASP.NET 2.0中的Output Caching


图1

如果想在缓存到期之前就终止缓存的话,有2个选择。一是通过编程调用 Response.RemoveOutputCacheItem(path)方法来移除某个页面的output cached,其中path是该页面的相对路径.另外,你还可以对output cache添加外部依赖,就像在文章
《Caching Page Output with Cache Key Dependencies》里探讨的那样.比如SQL Cache Dependencies,详情请参阅ASP.NET 2.0 QuickStarts的的《SQL Cache Invalidation》部分( http://quickstarts.asp.net/QuickStartv20/aspnet/doc/caching/SQLInvalidation.aspx ).


仅仅对页面的一部分进行Output Caching

默认情况下,output caching是针对整个页面缓存.不过在某些时候,我们希望页面的某些部分保持“刷新”(dynamic)。我们希望将那些系统开销大,不怎么变化的项——比如,要显示的数据进行缓存,而将广告、与某个用户相关的数据或其它频繁改变的信息保持"刷新".在ASP.NET 1.x里,我们只能通过fragment caching来实现,这样就达到了“页面的局部缓存而其它部分保持刷新”的目的.在ASP.NET 2.0也支持fragment caching,同时引入了post-cache substitution model,利用它我们可以实现“缓存页面,且保持某些部分刷新”的效果.让我们先看看fragment caching,再将注意力转移到post-cache substitutions.

Fragment caching原理在于创建一个包含User Control的页面,该页面没有用到output caching而由其包含的User Control使用output caching.本文的下载代码里包含了一个简单的示例,里面包含一个CachedUserControl.ascx用户控件,它将一个数据库表的记录显示出来,同时将检索数据的date/time值也反映出来.该User Control包含一个 <% @OutputCache %>声明,如下:

<%@ Control ... %>
<%@ OutputCache Duration="15" VaryByParam="None" %>

... markup that displays records from a database table ...

包含该User Control的页面并不包含<% @OutputCache %>声明.最终的结果是每次登录页面的时候都会重新绘制页面,但在每隔15秒的时间间隔内,该User Control只呈现一次(自然,也只访问数据库一次).

如下的截屏显示的是初次登录页面的情形。我们注意到页面和User Control显示的date/time值是一样的.隔几秒后再次登录页面,因为对User Control进行了缓存,页面的date/time值改变了,而User Control显示的date/time值依然是初次登录时的值.

ASP.NET 2.0中的Output Caching

图2

ASP.NET 2.0中的Output Caching

图3

除了本文的下载代码外,你还可以参阅文章《如何使用 Visual C# .NET 在 ASP.NET 中执行片段缓存》( http://support.microsoft.com/default.aspx/kb/308378 ),看如何按部就班的使用fragment caching.

通过Post-Cache Substitutions对缓存页面的局部保持"刷新"

ASP.NET 2.0新增加了一项技术post-cache substitutions—它可以将缓存的和需要"刷新"的内容有机的集合起来.就像其名称揭示的那样,该方法可以允许在一个使用了output caching的页面里,对缓存的内容实施“刷新”.你可以通过2种途径来使用它:

.Declaratively—使用Substitution控件来指定页面的动态刷新部分(dynamic portion). 你需要创建一个方法,用这些控件来调用这个方法来获取动态刷新部分的rendered markup.

.Programmatically— Response.WriteSubstitution(callback)method可以通过编程的方式注入一个response substitution模块。其中,参数callback是对某个方法的委托(delegate),这个方法被调用来获取要发送出去的markup.

要使用declarative方式的话,你只需要在output cached页面上要注入动态数据(dynamic data)的地方添加一个Substitution控件,如下:

<%@ Page ... %>
<%@ OutputCache Duration="duration" VaryByParam="paramList" %>
...
<asp:Substitution ID="id" runat="server" MethodName="method" />
...

其中MethodName(string)属性指定了一个页面后台代码类里的一个静态方法,该方法接受一个HttpContext object对象,返回string.比如,假设有一个包含缓存数据的页面,同时我们又想在页面上包含一个动态信息(比如,一个广告).这种情况下,我们在页面上希望显示该信息的区域添加一个Substitution控件:

<asp:Substitution ID="DynamicMessage" runat="server" MethodName="GetMessage" />

这里我们将MethodName指定为GetMessage. 因此,我需要在页面的后台代码里创建一个名为GetMessage,且返回一个string的静态方法:

'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的output caching属性允许对一个页面或User Control的整个HTML输入进行缓存,这有助于提升应用程序的总体性能.output caching逻辑是由OutputCacheModule来处理的.有时候,需要对页面的某个部分进行缓存,而其它部分则要保持刷新状态,为此,ASP.NET 2.0提供了2种解决办法:fragment caching 和 post-cache substitutions.对fragment caching而言,没有对页面实施output caching,对要实行缓存的部分我们可以使用User Control来实行,该用户控件被设置为使用output caching.另一个方法是使用post-cache substitution,此时需要设置页面使用output caching.将Substitution控件添加到页面以指出页面的哪个区域的内容在每次登录时都要进行动态更新,而不管页面是否被缓存.Post-cache substitutions是ASP.NET 2.0里新增加的功能.

祝编程快乐!

ASP.NET 2.0中的Output Caching


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

发表我的评论
最新评论 总共0条评论