Cache的一些总结
Cache.Add(key,value)或者Cache.Insert(key,value);
不加任何时间限制,增加的数据是不会过期的。
Add方法重复键值是不会在增加的,Insert数据是会覆盖重复的键值。
输出缓存
这是最简单的缓存类型,它保存发送到客户端的页面副本,当下一个客户端发送相同的页面请求时,此页面不会重新生成(在缓存有限期内),而是从缓存中获取该页面;当然由于缓存过期或被回收,这时页面会重新生成。
我们要实现输出缓存,只需在页面中添加如下代码:
<%@ 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文件设置如下:
<caching>
<!-- Sets out put cache profile-->
<outputCacheSettings>
<outputCacheProfiles>
<add name="ProductCacheProfile" duration="30"/>
</outputCacheProfiles>
</outputCacheSettings>
</caching>
现在,我们在页面中添加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还提供缓存项与文件之间的依赖关系,当文件被更新或删除对应的缓存项也将失效。