Enterprise LibraryV1.0-缓存应用程序块
缓存应用程序块
1、简介
我们知道,在Asp.net中有个System.Web.Caching名称空间,但在Windows Form中却没有System.Windows.Forms.Caching名称空间,当我们在WinForm程序中使用缓存时,往往会引用System.Web.Caching名称空间,用其缓存机制来解决缓存问题。但用起来毕竟感到有些别扭,缓存应用程序块应运而生,但其更大的作用在于Smart Client程序中缓存本地数据到数据库或其他存储位置。缓存应用程序块比起System.Web.Caching名称空间来有更好的一致性和扩展性,同时能满足WinForm应用程序、基于WinForm的Smart Client、Web等应用程序的缓存机制。如果在web程序中使用缓存,System.Web.Caching足以应付,关键是开发者要有意识的去使用,并灵活运用它。如果想使程序的缓存机制具有一致的策略、更加简洁的调用方法、更好的扩展性,还是要用缓存应用程序块。
在日常编程中,我们往往会由这样的需求:
1、 我们不断重复地使用相同的一组数据,这组数据来源于持久化设备,读取时要花费一定的资源和时间,我们希望获取数据之后缓存于本地,下一次读取时直接从本地内存中读取。
2、 我们希望离线的使用一组数据,这组数据从数据源(网络、数据库、Webservices等)得到后要持久化到本地,下一次读取时避免重新从数据源读取。
3、 当应用程序的客户端数目加大、数据吞吐量变大时,程序还能保持很好的性能,即程序有可扩展性。
4、 我们缓存的数据要及时更新,以便与数据源保持一致。
缓存应用程序块就是基于此目的设计的,其主要特点是:
1、 可以应用于各类应用程序。如WinForm应用程序、Smart Client、Web应用程序、Enterprise Services等。也可以应用到程序架构的不同Layer上。
2、 灵活可变的缓存Storage选择。支持isolated storage、Database、内存,而且可以无缝的切换。
3、 修改缓存策略时,不用修改源代码。
4、 支持过期后,自动删除策略。支持基于时间的过期设置,也支持基于文件变化的过期设置。如果用基于时间的过期策略,则可以是绝对时间、相对时间、自定义格式的时间等。
2、使用步骤
①用配置控制台添加缓存应用程序块。
添加步骤同其他应用程序块。
当使用基于内存的缓存策略时,有几个参数要设置,其中ExpirationPollFrequencyInSecond是指过期轮询周期,就是多长时间就检查一下有哪些缓存项过期了,由后台独立进程执行。这个参数很关键,如果时间设置的太短,就会使这个后台进程不断执行,占用大量CPU时间,如果太长,又会浪费内存,要找个不长不短的,因此推荐用性能计数器监测一下,选一个适中的参数。
添加完毕后,默认支持基于内存的缓存,你还可以添加多个缓存管理器Cache Manager,以使用不同的缓存策略。
②写代码添加缓存项
// 最简单的添加缓存项:这是最简单的一种,我们也最常用,直接建立默认的Cache Manager
CacheManager cacheManager = CacheFactory.GetCacheManager();
cacheManager.Add("key", myObject);
// 创建指定的Cache Manager
CacheManager cacheManager = CacheFactory.GetCacheManager("Custom Manager");
cacheManager.Add("key", myObject);
// 基于绝对过期时间的缓存
// 过期是指当到了指定时间后,系统会将此缓存项清除掉,如果你再次访问的话,会重建。
CacheManager isolatedCacheManager = CacheFactory.GetCacheManager("Isolated Cache Manager");
DateTime refreshTime = new DateTime(2005, 7, 28, 17, 10, 10);
AbsoluteTime expireTime = new AbsoluteTime(refreshTime);
isolatedCacheManager.Add("myKey",dataSet, CacheItemPriority.Normal, null, expireTime);
// 注意上面这个例句是Isolated Storage基于隔离缓存的,可以看出Client代码的写法与用内存、数据库来缓存的代码完全一样,这保证了当你的缓存策略发生改变时,Client代码不用作任何修改。
// 相对过期时间的缓存
TimeSpan timeSpan = new TimeSpan(0, 10, 0);
SlidingTime expireTime = new SlidingTime(timeSpan);
cacheManager.Add("myKey1", cachedObject, CacheItemPriority.Normal, null, expireTime);
CacheManager有只有两个重载的Add方法,其Sign如下:
public void Add(string key, object value);
public void Add(string key, object value, CacheItemPriority scavengingPriority, ICacheItemRefreshAction refreshAction, params ICacheItemExpiration[] expirations);
// 自定义格式的过期设置
// 格式为:<Minute> <Hour> <Day of month> <Month> <Day of week>
// 如:3 * * * *表示每小时的第3分钟就过期
// * 1 * * *表示每天凌晨1点的每分钟
// 15 2 * * *表示每天2点15都会过期
ExtendedFormatTime expireTime = new ExtendedFormatTime("0 1 * * 5");
cacheManager.Add("key", cachedObject, CacheItemPriority.Normal, null, expireTime);
// 依赖于文件的过期机制
FileDependency expireNotice = new FileDependency("文件名");
productsCache.Add("key", cachedObject, CacheItemPriority.Normal, null, expireNotice);
缓存应用程序块还提供了过期提醒机制,不过这要实现ICacheItemRefreshAction接口,用于过期时执行一些自定义的操作,比如提醒。
③写代码读取缓存项
这个与我们以往System.Web.Caching的用法基本一致。
public BizEntry ReadBizEntryByID(string bizEntryKey)
{
BizEntry bizEntry = (Product)cache.GetData(bizEntryKey);
if (bizEntry == null)
{
// 这里如果被执行说明缓存缓存中没有
// 此处的正常代码逻辑是先建立一个BizEntry对象
// 再将这个BizEntry对象放到缓存中,当然也可以不放进去
}
}
这里用的是CacheManager的GetData()方法:public object GetData(string key);
注意这里要进行强制类型转换。
BizEntry bizEntry = (Product)cache.GetData(bizEntryKey);
或者
BizEntry bizEntry = cache.GetData(bizEntryKey) as BizEntry;