Cache的一些总结
阅读原文时间:2023年07月11日阅读:1

输出缓存

这是最简单的缓存类型,它保存发送到客户端的页面副本,当下一个客户端发送相同的页面请求时,此页面不会重新生成(在缓存有限期内),而是从缓存中获取该页面;当然由于缓存过期或被回收,这时页面会重新生成。

我们要实现输出缓存,只需在页面中添加如下代码:

<%@ OutputCache Duration="23" VaryByParam="None" %>

它支持五个属性,其中两个属性Duration和VaryByParam是必填的

Duration

必需属性。页面应该被缓存的时间,以秒为单位。必须是正整数。

Location

指定应该对输出进行缓存的位置。如果要指定该参数,则必须是下列选项之一:Any、Client、Downstream、None、Server 或 ServerAndClient。

VaryByParam

必需属性。Request 中变量的名称,这些变量名应该产生单独的缓存条目。"none" 表示没有变动。"*" 可用于为每个不同的变量数组创建新的缓存条目。变量之间用 ";" 进行分隔。

VaryByHeader

基于指定的标头中的变动改变缓存条目。

VaryByCustom

允许在 global.asax 中指定自定义变动(例如,"Browser")。

表1输出缓存属性

这里我们把输出缓存的有效期设置为23秒,也就是说,当缓存超过有效期就会被回收;当用户再次请求该页面时,就要重新创建页面。

前面我们介绍了输出缓存的使用,只需在页面中添加OutputCache指令,假设我们要在几个页面中添加输出缓存这可能比较简单,但我们要在几十个页面中添加输出缓存功能,而且前面介绍的例子中Duration属性值都是直接Hard code到每个页面中,如果我们需要修改Duration属性值,那么就必须修改每个页面了,ASP.NET还需要重新编译这些页面,这不利于我们的维护,最重要的是增加了我们的工作量。

其实,我们可以在web.config文件中定义一个outputCacheProfile(ProductCacheProfile),然后在页面中添加CacheProfile属性并且赋值为ProductCacheProfile,web.config文件设置如下:

现在,我们在页面中添加CacheProfile属性,并且设置为ProductCacheProfile,如下所示:

<%@ OutputCache CacheProfile="ProductCacheProfile" VaryByParam="None" %>

客户端缓存

另一种选择是客户端缓存,如果用户在浏览器中点击“后退”按钮或在地址栏中重新输入URL,那么在这种情况下,浏览器将从缓存获取页面;然而,如果用户点击“刷新”按钮,那么浏览器中缓存将失效,浏览器发送页面请求。

如果我们要使用客户端缓存,只需指定OutputCache中的属性Location=”Client”就OK了,具体代码如下所示:

<%@ OutputCache Duration="23" VaryByParam="None" Location="Client" %>

Query String缓存

如果查询参数和前一个请求相同并且该页面缓存有效,那么缓存将被重用,否则,创建一个新的页面缓存。

前面我们把VaryByParam设置为“*”,所以ASP.NET程序对ProductName和ProductId都创建页面缓存

如果我们只针对ProductName创建页面缓存,这时我们可以修改VaryByParam,具体如下所示:

<%@ OutputCache Duration="30" VaryByParam="productname" %>

自定义缓存控件

我们可以通过设置VaryByCustom属性来实现。

假设,现在我们要设计基于不同UserHostName的缓存,由于程序在执行过程中,首先调用全局方法GetVaryByCustomString()来确定是否缓存页面或重用现有的,所以我们可以通过重写GetVaryByCustomString()方法实现基于UserHostName的缓存,首先我们创建一个Global.asax文件然后重新全局方法GetVaryByCustomString()具体实现如下:

public override string GetVaryByCustomString(HttpContext context, string custom)

{

if (string.Equals(custom, "UserHostName", StringComparison.OrdinalIgnoreCase))

{

// Indicates that the cache should be vary on user host name.

return Context.Request.UserHostName;

}

return base.GetVaryByCustomString(context, custom);

}

前面我们重写了GetVaryByCustomString()方法,使得UserHostName值不同时,获取相应的缓存值。

然后让程序基于UserHostName创建缓存,所以我们要在页面添加以下代码:

<%@ OutputCache Duration="30" VaryByParam="None" VaryByCustom="UserHostName" %>

我们通过自定义现在GetVaryByCustomString()方法,实现了Web程序根据UserHostName实施不同的缓存方式,其实,我们还可以实现更多种类缓存方案,例如:基于用户角色、时间和Url等等。

片段缓存

为了实现片段缓存,我们需要创建自定义控件缓存部分页面,然后我们把OutputCache指令添加到自定义控件中,这样整个页面将不会被缓存,而自定义缓存控件除外。

数据缓存

Cache对象是线程安全:这表示无需显式实现锁定或解锁,在添删Cache对象中的元素,然而,在Cache对象中元素必须是线程安全的。例如,我们创建一个实体Product,而且存在多个客户端可能同时操作该对象的情况,这时我们必须为实体Product实现锁定和解锁操作(同步操作请参考《单例模式(Singleton)的6种实现》)。

Cache对象中的缓存项自动移除:当缓存过期,依赖项被修改或内存不足缓存ASP.NET会自动移除该缓存项。

缓存项支持依赖关系:我们可以给缓存项添加文件、数据库表或其他资源类型的依赖关系。

缓存的依赖关系

缓存项之间的依赖

ASP.NET Cache允许我们建立缓存之间的依赖关系,即一个缓存项依赖于另一个缓存项;以下示例代码创建了二个缓存项,并且它们之间建立依赖关系。具体实现如下:

// Creates cache object Key1.

Cache["Key1"] = "Cache Item 1";

// Makes Cache["Key2"] dependent on Cache["Key1"].

string[] dependencyKey = new string[1];

dependencyKey[0] = "Key1";

// Creates a CacheDependency object.

CacheDependency dependency = new CacheDependency(null, dependencyKey);

// Establishs dependency between cache Key1 and Key2.

Cache.Insert("Key2", "Cache Item 2", dependency);

现在,当Key1缓存项更新或从缓存中删除,Key2缓存项就会自动从缓存删除。

文件依赖

前面我们介绍了缓存项之间的依赖关系,ASP.NET Cache还提供缓存项与文件之间的依赖关系,当文件被更新或删除对应的缓存项也将失效。