ASP.NET中的缓存






4.79/5 (191投票s)
ASP.NET 缓存概述。
引言
动态网站中的大多数页面(如果不是全部)都是动态的。也就是说,这些页面是根据用户请求创建的。众所周知,动态网页有助于提供动态内容,为请求页面的用户定制内容(例如:用户的首页)。动态页面还有助于提供从不断变化的数据存储中获取的动态内容,而无需管理员在数据存储中发生任何变化时更改页面内容(例如:出版商网站上的图书列表)。缺点是为每个用户请求创建页面的开销。
为了克服这个问题,一些网站有页面创建引擎,它们一次性创建所有页面并将它们保存为 HTML 页面,然后将这些页面提供给用户。但这只适用于页面内容对所有请求都相同(与用户无关)的场景,如上例二所示。无论哪个用户请求页面,图书列表都是相同的。即使通过查询字符串提供不同的类别 ID 值可以按类别列出图书,特定类别图书的页面输出对所有用户来说也是相同的。
ASP.NET 提供“缓存”支持,这将帮助我们很大程度上解决这个问题。它可以缓存(存储在内存中)页面生成的输出,并将此缓存内容用于未来的请求。这仅在前面描述的第二种场景中有用,即页面内容对所有请求都相同(与用户无关)。缓存功能可以通过各种方式进行自定义,我们将在本文中看到如何实现。
缓存页面
为了缓存页面的输出,我们需要在页面顶部指定一个 @OutputCache
指令。语法如下所示:
<%@ OutputCache Duration=5 VaryByParam="None" %>
如您所见,此指令有两个属性。它们是:
Duration
- 输出应该被缓存的时间,以秒为单位。在指定持续时间过后,缓存的输出将被删除,并为下一个请求生成页面内容。该输出将再次被缓存 5 秒,此过程重复。VaryByParam
- 此属性是强制性的,指定用于改变缓存的查询字符串参数。在上面的代码片段中,我们将
VaryByParam
属性指定为None
,这意味着无论通过查询字符串传递的参数如何,要提供的页面内容都是相同的(请参阅示例下载中的示例 1)。如果对同一页面有两个请求,其查询字符串参数不同,例如:.../PageCachingByParam.aspx?id=12 和 .../PageCachingByParam.aspx?id=15,并且为每个请求生成了单独的页面内容,则指令应为:
<%@ OutputCache Duration=5 VaryByParam="id" %>
这两个请求的页面内容将各自缓存,缓存时间由
Duration
属性指定(请参阅示例下载中的示例 2)。要指定多个参数,请使用分号分隔参数名称。如果我们将
VaryByParam
属性指定为*
,则缓存内容将根据通过查询字符串传递的所有参数而变化。
有些页面会为不同的浏览器生成不同的内容。在这种情况下,可以为不同的浏览器改变缓存输出。@OutputCache
指令必须修改为:
<%@ OutputCache Duration=5 VaryByParam="id" VaryByCustom="browser" %>
这将不仅为浏览器,还会为其主要版本改变缓存输出。也就是说,IE5、IE6、Netscape 4、Netscape 6 都将获得不同缓存版本的输出。
缓存页面片段
有时我们可能只想缓存页面的一部分。例如,我们的页面可能有一个页眉,其内容对所有用户都相同。页眉中可能有一些文本/图像会每天更改。在这种情况下,我们希望将此页眉缓存一天。
解决方案是将页眉内容放入用户控件中,然后指定用户控件内容应被缓存。此技术称为“片段缓存”。
要指定用户控件应被缓存,我们使用 @OutputCache
指令,就像我们用于页面一样。
<%@ OutputCache Duration=10 VaryByParam="None" %>
使用上述指令,用户控件内容将缓存由 Duration
属性指定的时间(10 秒)。无论查询字符串参数、浏览器类型和/或版本如何,都将提供相同的缓存输出。[有关演示,请参阅下载中的示例 3]。
数据缓存
ASP.NET 还支持将数据作为对象进行缓存。我们可以将对象存储在内存中,并在应用程序的各个页面中使用它们。此功能是使用 Cache
类实现的。此缓存的生命周期与应用程序的生命周期相同。对象可以以名称值对的形式存储在缓存中。字符串值可以如下插入到缓存中:
Cache["name"]="Smitha";
存储的字符串值可以像这样检索:
if (Cache["name"] != null)
Label1.Text= Cache["name"].ToString();
[参见示例 4 以作说明。]
要将对象插入到缓存中,可以使用 Add
方法或 Cache
类的不同版本的 Insert
方法。这些方法允许我们使用 Cache
类提供的更强大的功能。Insert
方法的其中一个重载用法如下:
Cache.Insert("Name", strName,
new CacheDependency(Server.MapPath("name.txt"),
DateTime.Now.AddMinutes(2), TimeSpan.Zero);
前两个参数是要插入的键和对象。第三个参数是 CacheDependency
类型,它帮助我们将此值设置为文件 name.txt 的依赖项。因此,当此文件更改时,缓存中的值将被删除。我们可以指定 null
表示没有依赖项。第四个参数指定应从缓存中删除值的时间。[请参见示例 5 以作说明。] 最后一个参数是“滑动过期参数”,它显示项目自上次访问时间后从缓存中删除的时间间隔。
当系统内存不足时,缓存会自动从内存中删除最不常用的项目。此过程称为“清除”。我们可以为添加到缓存中的项目指定优先级值,以便某些项目比其他项目具有更高的优先级。
Cache.Insert("Name", strName,
new CacheDependency(Server.MapPath("name.txt"),
DateTime.Now.AddMinutes(2), TimeSpan.Zero,
CacheItemPriority.High, null);
CacheItemPriority
枚举包含用于设置各种优先级值的成员。CacheItemPriority.High
为项目分配一个优先级级别,以便该项目最不可能从缓存中删除。
关注点
- 如果您的网站中有使用
Response.Expires
属性来缓存页面输出的旧 ASP 页面,它们可以保持原样。ASP.NET 也支持此属性。 Cache
类的Insert
方法将覆盖任何具有相同键名的现有项。CacheItemPriority.NotRemovable
优先级值可以与Cache.Insert
方法一起使用,以设置项目的优先级级别,从而在清除过程中不会从缓存中删除该项目。
结论
在本文中,我试图概述 ASP.NET 中可用的各种缓存选项。为了保持文章简短,没有提供详尽的解释和细节。
片段缓存可以以嵌套方式进行,其中子控件启用了缓存。由于我尚未亲自尝试,因此未涵盖如何实现这一点。同样,本文也未讨论 Cache
类的各种 Insert
方法的重载。我希望本文能为读者深入了解 ASP.NET 中一个出色功能的细节提供一个良好的起点。
下载次数
示例 ASP.NET 应用程序展示了我们在本文中介绍的各种功能。使用 index.htm 获取所有插图的列表。
历史
- 2004 年 2 月 23 日 - 第一个版本。