缓存是用于提供应用程序执行效率的,应用程序大部分的花费都用于数据的获取,这些处理主要移动到网络上或者存储到硬盘中,但是某些数据不太会改变,并不需要每次都同步。
因此,为了提高应用程序的执行效率,找到一个很好的方法来处理这些不太改变的数据库,Catel使用了一个
CatchStorage<TKey,TValue>的类,注意,第一个泛型的参数表示的是关键字的类型,第二个泛型的参数是要存储的值的类型,就像Dictonary<Tkey,TValue>。但是CatcheStorage不仅仅是一个Dictionary,这个类允许你使用一条语句获取数据并将数据存储到缓存中。并且当你需要的时候,你可以使用终结策略。
1, 初始化内存存储
需要初始化内存存储时,可以使用如下语句:
private readonly CacheStorage<string, Person> _personCache = new CacheStorage<string, Person>(storeNullValues: true);
2 使用语句获取数据并将其存储到缓存中
使用如下语句
var person = _personCache.GetFromCacheOrFetch(Id, () => service.FindPersonById(Id));
当这个语句使用相同的Key执行多次的时候,这个语句将会从内存上返回,而不是从服务调用上返回。这个服务只是在第一次被执行,这个项可以被手工移除或者通过过期策略自动移除。
3 使用缓存的过期策略
缓存的过期策略是给缓存存储项目一个删除行为,当项目过期后,一个策略信号将发送给缓存存储,缓存存储将自动的移除这个项目。
在构造的时候可以给这个CatchStorage 制定过期策略
CacheStorage<string, Person> _personCache = new CacheStorage<string, Person>(() => ExpirationPolicy.Duration(TimeSpan.FromMinutes(5)), true);
如果未指定存储策略,则会制定默认过期策略。
4 创建过期策略
Catel自带过期策略:
过期策略 | 类型 | 描述 | 初始化代码例子 |
AbsoluteExpirationPolicy | 基于时间 | 缓存将在达到过期时间后过期,使用绝对时间 | ExpirationPolicy.Absolute( new DateTime( 21 , 12 , 2012 )) |
DurationExpirationPolicy | 基于时间 | 使用TimeSpan方法来定义当前时间的一个实际段,超过时间段后过期 | ExpirationPolicy.Duration(TimeSpan.FromMinutes( 5 )) |
SlidingExpirationPolicy | 基于时间 | 使用TimeSpan方法来定义当前时间的一个实际段,超过时间段后过期,但当其重新被回去过后,会重新计算时间 | ExpirationPolicy.Sliding(TimeSpan.FromMinutes( 5 )) |
CustomExpirationPolicy | 自定义 | 缓存过期将通过函数来进行判断,下面的例子说明了如何使用custom过期策略来创建一个silding策略 |
var startDateTime = DateTime.Now;
|
CompositeExpirationPolicy | 自定义 | 组合多种过期策略在一起,当任何一个策略过期的时候,都可以使其过期 |
new CompositeExpirationPolicy().Add(ExpirationPolicy.Sliding(
|
2.5 实现你自己的过期策略
如果CustomExpiationPolicy还是不够用,你也可以自己创建过期策略,在某个事件触发后使得缓存项目过期,也可以在读取缓存项目后,重新设置过期策略(如SlidingExpirationPolicy),要实现这个项目,可以使用如下的代码模板:
public class MyExpirationPolicy : ExpirationCachePolicy { public MyExpirationPolicy():base(true) { } public override bool IsExpired { get { // Add your custom expiration code to detect if the item expires } } public override void OnReset() { // Add your custom code to reset the policy if the item is read. } }
注意:构造函数中有一个参数来制定,策略是被重置,那么,你调用构造函数使用false,在调用OnReset方法,将不会再调用。