65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET中的缓存

2004年2月22日

CPOL

6分钟阅读

viewsIcon

716496

downloadIcon

10942

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 日 - 第一个版本。
© . All rights reserved.