Enterprise Library 4 缓存应用程序块的设计

缓存应用程序为以下目的而设计:

  • 提供一个大小可管理的 API 集合。
  • 允许开发人员添加标准的缓存操作到他们的应用程序中,而不用学习应用程序块的内部工作。
  • 用 Enterprise Library 配置控制台来简化配置。
  • 有效率的执行。
  • 线程安全。某些东西在被多个程序线程调用而没有属于那些线程的不必要的交互时,它被视为是线程安全的。
  • 如果在访问后端存储时发生异常,确保后端存储依然是完整的。
  • 保存内存缓存的状态与后端存储保持同步。

设计亮点
图 1 说明了缓存应用程序块中关键类的相互关系。

 

当使用 CacheFactory 初始化一个 CacheManager 的实例时,它在内部创建了一个 CacheManagerFactory 对象,然后创建一个Cache 对象。在 Cache 对象被创建后,所有在后端存储中的数据被加载到一个包含中 Cahce 对象的内存表示中。然后应用程序就可以向 CacheManager 对象发出请求以获取缓存的数据、添加数据到缓存以及从缓存中移除数据。
当应用程序使用 Add 方法发送一个请求到 CacheManager 对象以添加条目到缓存中时,CacheManager 对象又将请求发送给 Cache 对象。如果已存在同样键的的条目,Cache 对象会在添加新条目到内存缓存和后端存储之前删除它。如果后端存储是默认的 NullBackingStore ,数据将只是写到内存中。如果在条目添加时已缓存条目的数量已超出了预先设置的限制,BackgroundScheduler 对象将开始清理。在添加条目时,应用程序可以使用 Add 方法的一个重载来指定一个过期策略数组、清理优先级,以及一个实现了 ICacheItemRefreshAction 接口的对象。
当添加的条目没有在内存哈希表中时,Cache 对象首先创建一个模型缓存条目并将它添加到内存哈希表中。然后锁定内存哈希表中的条目,添加条目到后端存储中,最后用新的缓存条目替换掉在内存哈希表中的条目。(在条目已存在于内存哈希表中的情况下,它替换模型条目。)如果在写入后端存储时发生了异常,它会移除添加到内存哈希表中的模型条目且不再继续。缓存应用程序块强制了一个强壮的异常安全保证。这意味着,如果 Add 操作失败,缓存的状态将回滚到尝试添加条目以前的状态。换句话说,操作要么完全成功,要么缓存的状态保持不变。(这也同样适用于 Remove 和 Flush 方法。)
BackgroundScheduler 对象周期性的监视缓存中条目的生命期。当条目过期时,BackgroundScheduler 对象首先移除它,然后可能通知应用程序条目已被移除。此时,应用程序的响应时刷新缓存。

详细设计
CacheManager 类是缓存应用程序块其余部分和应用程序之间的接口,所有的操作都通过此类。对于使用没有修改过的应用程序块的开发人员,CacheManager 对象提供了所有添加、获取和从缓存中移除条目的所需方法。通过 CacheManager 对象调用的所有方法都是线程安全的。
要创建 CacheManager 对象实例,应用程序要使用 CacheFactory 类,然后使用 CacheManagerFactory 类。CacheManagerFactory 类创建所有实现 CacheManager 所需要的内部类。
每个名称只能用于一个缓存,要创建多个缓存的实例,就得使用多个名称。要注意的是,不同的缓存,也就是不同名称的缓存,不能共享同样的后端存储。每个 CacheManager 对象也只有一个后端存储。
Cache 对象接收来自 CacheManager 对象的请求,并实现所有缓存数据的后端存储和内存表示之间的操作。它包含一个保存数据内存表示的哈希表。( 这是用户看到的格式。)一个数据条目被包装成一个 CacheItem 对象,此对象包含了数据本身,以及如条目的键、优先级、RefreshAction 对象和过期策略(或策略数组)等其他信息。它被存储在哈希表中。Cache 对象还使用一个同步的哈希表来控制应用程序和 BackgroundScheduler 对缓存中条目的访问。Cache 对象为整个缓存应用程序块提供了线程安全。
BackgroundScheduler 对象的职责是终止过期的缓存条目和清理低优先级的缓存条目。一个 PollTimer 对象会触发过期周期,以及一个数量限制会触发清理进程,这些都在配置文件中进行设置。
BackgroundScheduler 对象是主动对象模式( Active Object Pattern )的一个实现。这意味着与 BackgroundScheduler 对象会话的其他对象(在此是 PollTimer )就像已存在于调用对象的线程中。在它被调用后,BackgroundScheduler 将请求打包成一条消息,并将它放到一个队列集合对象中,而不是马上执行所请求的行为。(记住,这都发生在调用者的线程中。)这个队列是生产者/消费者(Produceer-Consumer)模式的一个示例。当BackgoundScheduler 处理完消息时,一个内部线程将从队列中取出消息。实际上,BackgoundScheduler 串行化了所有清理和过期请求。
对于它自己的线程,BackgroundScheduler 对象按顺序从队列中移除消息,然后执行请求。对于过期过程,它调用ExpirationTimeoutExpiredMsg 类的 Run 方法。对于清理过程,它调用 StartScavengingMsg 类的 Run 方法。在一个单一线程中顺序执行操作的好处是保证代码运行在单一线程的环境中,这使代码和它的影响更容易理解。
包含在缓存应用程序块中的缓存存储类是 DataBackingStore 类、IsolatedStorageBackingStore 类和 NullBackingStore 类。如果有兴趣开始自己的后端存储,你的类必须实现 IBackingStore 接口,或者从实现了 IBackingStore 接口的抽象类 BaseBackingStore 继承。此类包含了普通策略的实现和可以用于所有后端存储的实用方法。
DataBackingStore 类在后端存储是数据访问应用程序块时被使用。用配置控制台配置它使用一个命名的数据库实例。IsolatedSorageBackingStore 类在特定域隔离的存储中存储缓存条目。用配置控制台可以配置它使用一个命名的独立存储。缓存应用程序块通过 IBackingStore 接口与所有的后端存储隔离。
DataBackingStore 和 IsolatedStorageBackingStore 类可以在持久存储前加密缓存条目数据。缓存条目数据的加密可以通过配置使其可用。使用配置控制台,缓存存储可以配置为使用命名的对象加密算法提供程序。命名的提供程序也可以在用条目数据组装缓存之前从缓存存储中读取数据,解密数据时使用。

过期处理的设计

缓存应用程序块的过期处理由 BackgroundScheduler 来执行。它周期性的检查哈希表中的 CacheItem 看是否有条目已过期。在使用配置控制台配置一个 CacheManager 实例时可以控制过期周期发生的频率。
缓存应用程序块提供了四个过期策略:

· 绝对时间(Absolute)。这意味着条目在特定的时间过期。

· 滑动时间(Sliding)。在此的意思是在从它最后一次被访问后经过了指定时间后过期。默认的时间是 2 分钟。

· 扩展格式。这允许开发人员更细致的处理条目何时过期。例如,可以指定条目在每个星期六的晚上 10:03 分过期,或者在一个月的第三个星期二过期。扩展格式都列出在 ExtendedFormat.cs 文件中。

· 文件依赖。条目在特定文件被修改后过期。

前面三个策略,绝对时间、滑动时间和扩展格式都可认为是基于时间的过期。可以将基于时间的过期用于短暂的缓存条目,例如那些定期刷新或仅在指定时间有效的条目。基于时间的过期让你设置仅在缓存中保持最新的条目的策略。例如,如果编写了一个跟踪当前汇率的的应用程序,汇率数据从一个频率更新的 Web 站点上获取,就可以缓存当前汇率为那些汇率在源 Web 站点上保持不变的时间。在这种情况下,将设置基于 Web 站点更新频率的过期策略。
第四种策略,文件依赖,可以认为是一种基于通知的过期。它定义了缓存的条目的有效性基于一个特定的文件。如果文件被修改,缓存的条目就不再有效并从缓存中移除。
Add 方法有二个重载。NeverExpired 接受默认的过期策略,另一个重载允许自己设置过期策略。可以使用你能想到的所有策略,包括自己创建的策略。(关于用添加自己的过期策略来扩展缓存应用程序的更多详细信息,请参见添加新的过期策略。)如果有一个有多个策略的条目,条目将在最严格的策略到来时过期。
标记和清除
过期是一个两部分的过程。第一部分可以认为是标记,第二部分可以认为是清除。处理分成隔离的任务是为了避免如果应用程序使用 BackgroundScheduler 试图过期的条目可能发生的冲突。
在标记期间,BackgroundScheduler 标记哈希表的一个副本,并检查其中的每个缓存条目看它是否可以被过期。在它这样做时,它锁定了条目。如果条目可以过期,BackgroundScheduler 给在缓存中条目设置一个标记。
在清除期间,BackgroundScheduler 重新检查每个标记的 CacheItem ,看它在标记后是否被访问过。如果它被访问过话,条目将保持在缓存中。如果它没有被访问,它将被过期并从缓存中移除。在条目过期时会触发一个 Windows Management Instrumentation( WMI )事件。
回调
可选择的是,开发人员可以使用 Add 方法的一个重载来指定应用程序在条目过期并从缓存中移除后接收一个回调。如果需要,应用程序将刷新缓存。
条目也许可以在应用程序退出时依在缓存中,并且可能在应用程序重启时其中许多已过期。在这种情况下,条目保持在缓存中,并且条目的回调发生在第一个过期周期期间。然而,如果应用程序在第一个过期周期发生前请求一个过期的条目,缓存将执行回调,并返回 null 给应用程序。这确保每个过期条目回调的发生,并防止应用程序接收到一个过期的条目。

清理处理设计

缓存应用程序块的清理处理由 BackgroundScheduler 对象执行。它在每次添加条目时检查缓存,看缓存中条目的数量是否已到了预定的限制。可以在使用配置控制台配置一个缓存管理器实例时设置这个限制,也可以设置在清理开始后要从缓存中移除多少个条目。
在条目添加到缓存时,它可以被给予这四个优先级之一:Low, Normal, High 或者 Not Removable 。BackgroundScheduler 对象用基于优先级的主排序和基于条目最后访问时间的次排序来决定哪个条目将被删除。例如,才被使用过的 Low 优先级的条目将在已三年没有访问过的 High 优先级之前被清理。默认值是 Normal 。
NotRemoveable 优先级被用在当要条目保持在缓存中直到它到期时。然而,缓存不能仅使用为数据条目已存在的位置。缓存将用于提高性能,不使用为永久存储的形式。
不像过期处理,清理处理在单一过程中执行标记和清除。关于标记和清除的更多信息过期处理设计。

时间: 2024-11-12 02:15:33

Enterprise Library 4 缓存应用程序块的设计的相关文章

Enterprise Library 4 缓存快速入门

快速入门使用了一个顶层的处理程序来捕获任何场景中的任何异常.处理程序显示了一个带有异常信息的对话框. 快速入门在构建和运行应用程序之前不需要执行任何安装步骤.[注意:默认的快速入门配置不使用持久后端存储.] 快速入门提供两个版本.第一个版本使用工厂创建Enterprise Library 对象,例如使用CacheFactory.GetCacheManager 方法创建CacheManager 实例, 以及使用new操作符创建ProductData 实例. 第二个版本演示了集成Unity 应用程序

Enterprise Library 4.0缓存应用程序块

英文原文:http://msdn.microsoft.com/zh-cn/library/cc511588(en-us).aspx Enterprise Library 缓存应用程序块允许开发人员在应用程序中合并一个局部缓存,它支持内存内的缓存,和可选的可以是数据库存储或独立存储的后端存储.应用程序块可以不做修改的使用,它提供所有必须的获取.添加和移除缓存数据的功能.可配置的到期和清除策略也是应用程序块的一部分. 在构建企业范围发布的应用程序时,架构和开发人员都要面对许多挑战,缓存可以帮助他们战

Enterprise Library 2.0 Hands On Lab 翻译(9):缓存应用程序块(一)

练习1:使用缓存应用程序块提高性能 该练习将示范如何使用企业库中的缓存应用程序块,并用它提高显示数据的速度. 第一步 打开EmployeeBrowser.sln 项目,默认的安装路径应该为C:\Program Files\Microsoft Enterprise Library January 2006\labs\cs\Caching\exercises\ex01\begin,并编译. 第二步 在QuickStarts数据库中填充数据 运行批处理文件SetCachingHOL.bat,默认的安装

Enterprise Library 2.0 Hands On Lab 翻译(11):缓存应用程序块(三)

练习3:实现后台缓存 该练习将示范如何实现后台加载. 第一步 打开EmployeeBrowser.sln 项目,默认的安装路径应该为C:\Program Files\Microsoft Enterprise Library January 2006\labs\cs\Caching\exercises\ex03\begin,并编译. 第二步 实现后台加载 1.在解决方案管理器中选择EmployeeServices.cs文件,选择View | Code菜单命令,添加如下两个方法,它们将实现在后台加载

Enterprise Library 2.0 Hands On Lab 翻译(10):缓存应用程序块(二)

练习2:持久缓存 该练习将示范如何持久缓存. 第一步 打开EmployeeBrowser.sln 项目,默认的安装路径应该为C:\Program Files\Microsoft Enterprise Library January 2006\labs\cs\Caching\exercises\ex02\begin,并编译. 第二步 实现离线缓存 1.在解决方案管理器中选择EmployeeServices.cs文件,选择View | Code菜单命令并添加如下命名空间. using Microso

替换EnterPrise Library 4.0 缓存应用程序块的CacheManager

缓存是用来提高应用程序性能的常见技术,其实现方式是将常用数据从慢数据源复制到更快的数据源.对于数据驱动的应用程序来说,该技术通常需要将从数据库或 Web 服务检索到的数据缓存到本地计算机的内存中. 当缓存特定于每个应用程序时最容易实现缓存技术,但是如果多个应用程序需要使用一个公共缓存,那么问题将变得更具挑战性.例如,大型网站通常使用服务器场,其中包含多个提供相同内容的计算机.当每个请求到达时,它会被分配给场中的其中一台计算机.然而,如果信息缓存到场中的一台计算机内存中,其他计算机中的缓存就无法访

Enterprise Library 4 数据访问应用程序块

据穿过应用程序层( application layers).以及将修改的数据提交回数据库系统.应用程序块包含对存储过程和内联 SQL 的支持.常规内部(housekeep)处理,如管理连接.创建并缓存参数,都封装在应用程序块的方法中.换句话说,数据访问应用程序块在简单易用的类中提供了对 ADO.NET 的最常用的特性的访问:这提高了开发人员的工作效率. ADO.NET 2.0 提供了如 DbCommand 类和 DbConnection 这样的类,这些类有助于从任何特定数据库实现中抽象出数据提供

Enterprise Library Step By Step系列(一) 配置应用程序块

写在前面: 最近准备写Enterprise Library Step By Step的系列文章,对于每一个应用程序块,我都会用入门篇,进阶篇,剖析篇三篇文章去写. 在入门篇里会详细介绍应用程序块的使用步骤,主要是针对新手入门的:进阶篇会介绍一些应用程序块的更深的应用及扩展机制:剖析篇会去分析应用程序块的底层设计和类设计的一些内容.所有的观点都纯属个人理解,有不当之处请大家多多指教. 一.配置应用程序块概述: 几乎每一个应用程序都需要一些配置信息,这些信息可以是简单的数据库连接信息,或者复杂的多块

Enterprise Library 4.1学习笔记1----配置应用程序块(c/s和b/s均适用)

园子里TerryLee的Enterprise Library系列文章回顾与总结 http://www.cnblogs.com/Terrylee/archive/2006/08/01/464591.html已经写得很全面了,不过不是针对4.1版,一边看这一系列的文章学习,一边在4.1上摸索,准备写几篇学习笔记,今天先来认识Configuration Application Block(配置应用程序块) 参照TerryLee的文章,在4.1上怎么也找不到Configuration Applicati