缓存项的依赖关系 - 依赖其它缓存项
http://www.cnblogs.com/fish-li/archive/2011/12/27/2304063.html
缓存项的过期时间
ASP.NET支持二种缓存项的过期策略:绝对过期和滑动过期。
1. 绝对过期,这个容易理解:就是在缓存放入Cache时,指定一个具体的时间。当时间到达指定的时间的时,缓存项自动从Cache中移除。
2. 滑动过期:某些缓存项,我们可能只希望在有用户在访问时,就尽量保留在缓存中,只有当一段时间内用户不再访问该缓存项时,才移除它, 这样可以优化内存的使用,因为这种策略可以保证缓存的内容都是【很热门】的。 操作系统的内存以及磁盘的缓存不都是这样设计的吗?而这一非常有用的特性,Cache也为我们准备好了,只要在将缓存项放入缓存时, 指定一个滑动过期时间就可以实现了。
以上二个选项分别对应Add, Insert方法中的DateTime absoluteExpiration, TimeSpan slidingExpiration这二个参数。
注意:这二个参数都是成对使用的,但不能同时指定它们为一个【有效】值,最多只能一个参数值有效。 当不使用另一个参数项时,请用Cache类定义二个static readonly字段赋值。
这二个参数比较简单,我就不多说了,只说一句:如果都使用Noxxxxx这二个选项,那么缓存项就一直保存在缓存中。(或许也会被移除)
缓存项的依赖关系 - 依赖其它缓存项
ASP.NET Cache有个很强大的功能,那就是缓存依赖。一个缓存项可以依赖于另一个缓存项。 以下示例代码创建了二个缓存项,且它们间有依赖关系。首先请看页面代码: 
<body>
<p>Key1 的缓存内容:<%= HttpRuntime.Cache["key1"] %></p>
<hr />
<form action="CacheDependencyDemo.aspx" method="post">
<input type="submit" name="SetKey1Cache" value="设置Key1的值" />
<input type="submit" name="SetKey2Cache" value="设置Key2的值" />
</form>
</body>
public partial class CacheDependencyDemo : System.Web.UI.Page
{
[SubmitMethod(AutoRedirect=true)]
private void SetKey1Cache()
{
SetKey2Cache();
CacheDependency dep = new CacheDependency(null, new string[] { "key2" });
HttpRuntime.Cache.Insert("key1", DateTime.Now.ToString(), dep,
Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration);
}
[SubmitMethod(AutoRedirect=true)]
private void SetKey2Cache()
{
HttpRuntime.Cache.Insert("key2", Guid.NewGuid().ToString());
}
}
当运行这个示例页面时,运行结果如下图所示, 点击按钮【设置Key1的值】时,将会出现缓存项的内容(左图)。点击按钮【设置Key2的值】时,此时将获取不到缓存项的内容(右图)。

根据结果并分析代码,我们可以看出,在创建Key1的缓存项时,我们使用了这种缓存依赖关系:
CacheDependency dep = new CacheDependency(null, new string[] { "key2" });
所以,当我们更新Key2的缓存项时,Key1的缓存就失效了(不存在)。
不要小看了这个示例。的确,仅看这几行示例代码,或许它们实在是没有什么意义。 那么,我就举个实际的使用场景来说明它的使用价值。

上面这幅图是我写的一个小工具。在示意图中,左下角是一个缓存表CacheTable,它由一个叫Table1BLL的类来维护。 CacheTable的数据来源于Table1,由Table1.aspx页面显示出来。 同时,ReportA, ReportB的数据也主要来源于Table1,由于Table1的访问几乎绝大多数都是读多写少,所以,我将Table1的数据缓存起来了。 而且,ReportA, ReportB这二个报表采用GDI直接画出(由报表模块生成,可认是Table1BLL的上层类),鉴于这二个报表的浏览次数较多且数据源是读多写少, 因此,这二个报表的输出结果,我也将它们缓存起来。
在这个场景中,我们可以想像一下:如果希望在Table1的数据发生修改后,如何让二个报表的缓存结果失效?
让Table1BLL去通知那二个报表模块,还是Table1BLL去直接删除二个报表的缓存?
其实,不管是选择前者还是后者,当以后还需要在Table1的CacheTable上做其它的缓存实现时(可能是其它的新报表), 那么,势必都要修改Table1BLL,那绝对是个失败的设计。 这也算是模块间耦合的所带来的恶果。
幸好,ASP.NET Cache支持一种叫做缓存依赖的特性,我们只需要让Table1BLL公开它缓存CacheTable的KEY就可以了(假设KEY为 CacheTableKey), 然后,其它的缓存结果如果要基于CacheTable,设置一下对【CacheTableKey】的依赖就可以实现这样的效果: 当CacheTable更新后,被依赖的缓存结果将会自动清除。这样就彻底地解决了模块间的缓存数据依赖问题。

浙公网安备 33010602011771号