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 优先级被用在当要条目保持在缓存中直到它到期时。然而,缓存不能仅使用为数据条目已存在的位置。缓存将用于提高性能,不使用为永久存储的形式。
不像过期处理,清理处理在单一过程中执行标记和清除。关于标记和清除的更多信息过期处理设计。
本文来自云栖社区合作伙伴“doNET跨平台”,了解相关信息可以关注“opendotnet”微信公众号
相关文章:

【软件测试培训】了解jmeter分布式测试
一提到分布式测试,大家肯定会觉得,哇!好高大上,一定很高深的吧,这里老师推出不做傻白甜系列文章,带同学们一步一步理解jmeter的分布式测试。 首先我们来看下jmeter自动化测试的流程 ,见如下图1 【软件测试…

存储过程中返回结果集
存储过程中返回结果 从存储过程中返回结果有三种方式: 1、 返回结果集 这是客户端应用程序返回结果的最通用的方法。结果集是通过使用select语句选择数据产生的。结果集可以从永久表、临时表或局部变量中产生。将结果返回到另一个存储过程不是一种有效的方法。存储…

我的股票交易策略
投资股市已经成为我们进行资产配置的一个重要选择。在这个市场中主流的投资方式无外乎 价值投资 和 趋势投资 两种。价值投资需要了解各种财务指标来评价各支股票,在被市场低估时买入,在被市场高估时卖出。这对于非财务背景的人来说门槛偏高。趋势投资需…

你负责选歌,索尼负责用 AI 谱出风格相似的曲子
近日,索尼巴黎计算机科学实验室(CSL)正在开发一套算法系统 Flow Machines,该系统根据用户的品味谱写歌曲,其歌曲在迎合用户口味的基础上,适用于所有现有音乐风格。 技术人员搭建了一个拥有 13000 多首音乐的…

java培训:Java的十大算法
想要学好java语言,就要打好基础,java要学习的东西有很多,今天小编就来和大家说下java的十大算法。 算法一:快速排序算法 快速排序是由东尼霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(nlogn) 次比较。…

PetShop之表示层设计 - 《解剖PetShop》系列之六
六 PetShop之表示层设计 表示层(Presentation Layer)的设计可以给系统客户最直接的体验和最十足的信心。正如人与人的相交相识一样,初次见面的感觉总是永难忘怀的。一件交付给客户使用的产品,如果在用户界面(User Inte…

物联网时代营销怎么做?
这几年和大数据、O2O一样热门的词还包括“物联网”, 物联网是新一代信息技术的重要组成部分,也是“信息化”时代的重要发展阶段。其英文名称是:“internet of things(IoT)”。顾名思义,物联网就是物物相连的互联网。 说的再通俗一…
怎样去掉 CSDN-Markdown 上传图片中的水印
自己一直使用 Markdown 写技术图文,我们知道在 Markdown 中插入图片需要这个图片的URL地址,那么必须得找一个图床来存放图片。 // Markdown 中插入图片的语法结构 我的方法是这样的:在 CSDN 上发一篇…

Python编程比较好的机构怎么选择
想要进入到IT行业,很多人的首要选择都是学习Python编程语言,因为Python编程语言入门是相对比较简单的,但是想要学好Python技术,找一个好的Python培训机构是非常重要的,那么Python编程比较好的机构怎么选择呢?来看看下…
赚钱是刚需,如何正确的交易股票?
试着考虑下面这些情景: 听隔壁老王说,最近股市行情不错,自己也想买点股票,但不知道该买那支?犹犹豫豫到处打听消息。 买入一支股票后,时不时就会拿出手机看看它的价格,有时候甚至一天要看很多…

C# Windows CE使用小技巧实例
C# Windows CE使用的一些感受:使用Windows的开发机上用C#启动一个外部程序的方法有很多,但这些方法用在使用WinCE的目标工控机上都无能为力。 C# Windows CE使用1、 现在以打开一个IE为例,介绍如何在WinCE下使用C#来打开一个外部文件…

Ovirt 安装部署方法
官方的安装文档:http://www.ovirt.org/documentation/install-guide/Installation_GuideOvirt note 系统镜像的下载:http://www.ovirt.org/download http://mirror.isoc.org.il/pub/ovirt/ovirt-4.1/iso/ovirt-node-ng-installer-ovirt/4.1-2017072816/…

零基础如何选择适合的Java培训课程
很多人都想要学习java技术,但是害怕自己是零基础学不好,所以想要找专业的java培训机构进行学习,但是零基础如何选择适合的Java培训课程成了他们比较头疼的事情,下面小编就为大家做下详细的介绍。 零基础如何选择适合的Java培…

Android Intent的几种用法全面总结
Android Intent的几种用法全面总结 Intent, 用法Intent应该算是Android中特有的东西。你可以在Intent中指定程序要执行的动作(比如:view,edit,dial),以及程序执行到该动作时所需要的资料。都指定好后,只要调用startAct…
七天学会「股票数据分析软件」的开发(中)
两天前,我写了 七天学会「股票数据分析软件」的开发(上),号召大家尝试着写写代码,不知道大家进度如何。 如果存在掌握一种技能的刚需,而且知道正确的学习方法,经过刻意练习,这门技能…

《Oracle高性能SQL引擎剖析:SQL优化与调优机制详解》一1.1 生成执行计划
1.1 生成执行计划 在Oracle中,任何一条语句在解析过程中都会生成一个唯一的数值标识,即SQL_ID。而同一条语句,在解析过程中,可能会因为执行环境的改变(例如某些优化参数被改变)而生成多个版本的游标&#…

软件测试培训:高薪测试技术要掌握哪些
职业技能一 1. 软件测试: 1) 熟练灵活地运用等价类、边界值、判定表法、因果图法等各种方法设计测试用例,包括单元测试、集成测试、系统测试用例设计。 2) 牢固掌握了软件测试计划、测试日报、测试报告的写作方法与要领。 3) 针对B/S、C/S架构及不同…

MFC-4简单的窗口重绘(非部分重绘)
#include <afxwin.h> #include "resource.h" #include <afxtempl.h> //定义模板类的头文件class MyDocument : public CDocument { public:CArray<CPoint,CPoint &> pArray;//<保存的数据类型,读取保存数据类型的返回值>void AddPoint…
七天学会「股票数据分析软件」的开发(下)
昨天下午把《我不是药神》这部电影看了,搞得我哭的稀里哗啦,里面有一些情节触痛了内心中最薄弱的地方。药厂没有错,他们要收回前期投入的研发成本。主人公 程勇 只能算是整个事件的牺牲品,通过他的牺牲让国家关注到白血病人这个群…

那些对混合云开发和应用程序环境的错误认识
企业架构师们在开发混合云计算应用程序并为支持程序云计算而选择云计算供应商之前,他们应当好好完成他们的准备工作。选择错误的供应商和在错误的环境中开发应用程序都会对应用程序的运行性能、工作流程、变更成本、以及与客户的沟通和交易带来负面影响。 在本文中&…

2021年UI设计培训机构哪个好
想要学好UI设计,选择报一个专业的UI设计培训机构是非常明智的选择,为什么这么说呢?因为培训机构的课程都是根据当下的行业环境制作出来的,而且有专业老师,比自学要好很多,那么在2021年UI设计培训机构哪个好呢?来看看…

UVA 116 Unidirectional TSP DP
题目链接: https://uva.onlinejudge.org/index.php?optioncom_onlinejudge&Itemid8&category3&pageshow_problem&problem52 题目描述: 一个整数矩阵, 求第一列到最后一列的最小整数和, 只能从第一列出发向右&…

C++ 数据类型转换
wchar_t*,wchar_t,wchat_t数组,char,char*,char数组,std::string,std::wstring,CString....#include <string>// 使用CString必须使用MFC,并且不可包含<windows.h>#define _AFXDLL#include <afx.h>using namespace std;//-----------------------…
如何准备数学建模竞赛!
昨天早晨,我到教十一实验室的时候遇到史会峰老师,他说正准备给学生们进行数学建模的培训。今天早晨,我又遇到了孔令才老师,他同样也说准备给学生们进行数学建模的培训。看到这么多同事在做这个事情,想想自己也应该贡献…

UI设计培训:UI设计师离不开的基本版式设计
不管你是UI设计,还是工业设计,甚至动画设计,终究离不开基本的版式设计,所以版式设计这块非常考验设计师的基础功力。 1. 大且醒目&美观的排版设计 版面设计大概是一位设计师重要的部分,今年的版面设计会围绕着大且…

我对她说,你能不能换件衣服?换种心情?换种脾气?她说,可以,换个人就行了···...
我跟她说,你能不能换件衣服?换种心情?换种脾气?她说,可以,换个人就行了转载于:https://www.cnblogs.com/yangzhong/archive/2010/07/06/1772124.html
如何通过代码连接SQL Server数据库
我们曾经为南方电网做过几个有关架空线路的科技项目,要趁着假期有整段的空闲时间,把这些代码整理一下,放入团队刚刚重构的代码库中。 由于这些项目使用的数据库为 SQL Server,所以在整理代码之前需要解决两个问题: 把…

选择一个稳定、快速的服务器四大注意事项
要想运营好一个网站,稳定和高速的服务器是必不可少的。可是在选择的时候企业就会很发愁,不知道该考虑哪些因素,不知道该怎么选择,下面我们简单的了解一下如何选择一个稳定性好、快速的服务器。 第一 性能要稳定 为了保证网站能够正…

APP不同上线情况对应的测试流程
一个App软件从研发提测到版本上线都会经过哪些测试流程呢?很多人认为就是进行功能测试,没bug了就提交审核,审核通过就直接上线了,其实不然,有些步骤是需要特别关注的,否则极易造成线上bug,本文千锋教育小编…

iOS 进阶—— iOS内存管理
1 似乎每个人在学习 iOS 过程中都考虑过的问题 alloc retain release delloc 做了什么?autoreleasepool 是怎样实现的?__unsafe_unretained 是什么?Block 是怎样实现的什么时候会引起循环引用,什么时候不会引起循环引用?所以我将在本篇博文中详细的从 ARC 解释到…