SOA Framework 开发使用手册
public class MyFooDependency : DependencyBase { protected override void CacheItemBinded() { lock(regsiteredDependencies) { } InitMonitorNotifyThread(); } private static void InitMonitorNotifyThread() } { } lock (typeof(MyFooDependency)) { } if (MyFooDependency.monitorNotifyThread == null) { } Thread thread = new Thread(new ThreadStart(MonitorThread)); thread.IsBackground = true; MyFooDependency.monitorNotifyThread = thread; thread.Start(); regsiteredDependencies.Add(this); private bool expiredFlag = false; private static List
?《SOA Framework》 11
SOA Framework 开发使用手册
private static void MonitorThread() { while (true) { } private static void NotifyAllDependenciesChanged() { } lock (regsiteredDependencies) { } foreach (MyFooDependency dependency in regsiteredDependencies) dependency.expiredFlag = true; } try { } catch (System.Exception) { } Thread.Sleep(TimeSpan.FromSeconds(10)); if (DBDataChanged()) NotifyAllDependenciesChanged(); 监听线程MonitorThread每隔10秒钟检查数据库的中状态,如果发现数据变化,将所有相关依赖项的expiredFlagbia标记置为true。
10秒钟的轮询间隔可以根据具体业务进行调整,不过需要注意的是,即使间隔再短(短到极致就是0),也需要执行Thread.Sleep来释放CPU的时间片。
正如前文所述,真正Cache项的清除,是在后台清理程序执行后或访问该Cache项时。和真正的失效时间有一个延迟,要想在监听线程中同步清除,我们可以修改上面代码中的NotifyAllDependenciesChanged方法。
private static void NotifyAllDependenciesChanged() { } lock (regsiteredDependencies) { } foreach (MyFooDependency dependency in regsiteredDependencies) dependency.CacheItem.RemoveCacheItem(); 每个依赖项都有一个对应的CacheItem属性,CacheItem也有一个Queue属性,来表示它所属于的Cache字典。CacheItem的RemoveCacheItem就是从字典中删除自己。
?《SOA Framework》 12
SOA Framework 开发使用手册
2.6 缓存容器
框架中包含三种类型的Cache存储容器
?
CacheQueue
有长度限制的容器。这种容器的生命周期与应用程序相同,只有在应用程序被卸载的时候,才释放内存。
? PortableCacheQueue
没有长度限制的容器,与CacheQueue的生命周期一样。
?
ContextCacheQueueBase
上下文缓存容器,该容器的生命期仅仅在当前线程(WinForm)或一次Http(Web)请求过程中有效,请求结束后,缓存容器随即释放。
2.6.1 有长度限制的缓存容器(CacheQueue)
有长度限制的容器,内部利用LruDictionary容器,来存储CacheItem。LruDictionary容器会把最近使用的Cacheitem放在最前面,而最少使用的CacheItem放在最后面,从而实现快速索引频繁使用的CacheItem。由CacheManager统一扫描,或者在超出容器大小时,删除依赖过期项。CacheQueue只能在配置文件中设置缓存项的个数,默认值是100。这种容器的生命周期与应用程序相同,只有在应用程序被卸载的时候,才释放内存。
在这里,我们用两个不同类型的缓存容器来举例说明。
?《SOA Framework》 13
SOA Framework 开发使用手册
2.6.1.1 自定义缓存项
//自定义的缓存项 public class TestCacheItem1 { private int index; private string name; } //自定义缓存项 public class TestCacheItem2 { private int age; private string name; } 2.6.1.2 自定义缓存容器
定义两个装载项为上述两个类的缓存容器,在定义时需注意以下几点: ?
?
必须继承自MCS.Library.Caching.CacheQueue.
必须向CacheManager注册,否则无法实现定期清除过期缓存项。
由于CacheManager 中使用类型作为Dictionary的Key,所以必须使用单件,即保证类实例的单一性。否则在添加缓存项时,会覆盖或无法添加。
?
?《SOA Framework》 14
SOA Framework 开发使用手册
//定义一个缓存容器,此处必须为泛型封闭类,且必须继承CacheQueue类,装载项为TestCacheItem1 public class TestCacheQueue1 : CacheQueue