.NET Framework中,叫做System.Runtime.Caching,这不仅是个缓存库,还是个框架,可以在上面开发自己的库。ObjectCache定义了所有缓存都要实现的通用操作。与之搭配的是个内存缓存实现,叫做MemoryCache。这个缓存系统的结构如下:
上图大家可以看出来对应那些产品了吗?
下面我给大家介绍一个实现这样一个架构的代码示例,代码的核心就是ObjectCache:
定义一个抽象的Provider接口:
interface ICacheBuilder
2: {
3: ObjectCache GetInstance();
string DefaultRegionName { get; }
5: }
In-memory提供者的实现使用MemoryCache:
class MemoryCacheBuilder : ICacheBuilder
2: {
public MemoryCacheBuilder() { }
4:
public ObjectCache GetInstance()
6: {
return MemoryCache.Default;
8: }
9:
string DefaultRegionName
11: {
null; }
13: }
14: }
分布式缓存提供者Memcached:
class MemcachedCache : ObjectCache, ICacheBuilder
2: {
// default Expire Time
null;
#region ICache Members
6:
public MemcachedCache()
8: {
this._client = MemcachedClientService.Instance.Client;
10: }
11:
null)
13: {
);
value, regionName);
new CacheItemPolicy();
17: policy.AbsoluteExpiration = absoluteExpiration;
18:
19: Set(item, policy);
20: }
21:
void Set(CacheItem item, CacheItemPolicy policy)
23: {
null)
return;
26:
27: item.Key = item.Key.ToLower();
28:
null && policy.ChangeMonitors.Count > 0)
);
31:
// max timeout in scaleout = 65535
null)) ?
34: policy.SlidingExpiration :
35: (policy.AbsoluteExpiration - DateTimeOffset.Now);
36:
double timeout = expire.TotalMinutes;
if (timeout > 65535)
39: timeout = 65535;
if (timeout > 0 && timeout < 1)
41: timeout = 1;
42:
this._client.Store(Enyim.Caching.Memcached.StoreMode.Set, item.Key.ToString(), item.Value);
44:
45: }
46:
string key]
48: {
49: get
50: {
return Get(key);
52: }
53: set
54: {
null);
56: }
57: }
58:
null)
60: {
61: CacheItem item = GetCacheItem(key, regionName);
null)
63: {
value, regionName), policy);
value;
66: }
67:
return item.Value;
69: }
70:
value, CacheItemPolicy policy)
72: {
value.RegionName);
null)
75: {
value, policy);
value;
78: }
79:
return item;
81: }
82:
null)
84: {
value, regionName);
new CacheItemPolicy();
87: policy.AbsoluteExpiration = absoluteExpiration;
88:
return AddOrGetExisting(item, policy);
90: }
91:
null)
93: {
false;
95: }
96:
null)
98: {
new System.NotImplementedException();
100: }
101:
override DefaultCacheCapabilities DefaultCacheCapabilities
103: {
104: get
105: {
return
107: DefaultCacheCapabilities.OutOfProcessProvider |
108: DefaultCacheCapabilities.AbsoluteExpirations |
109: DefaultCacheCapabilities.SlidingExpirations |
110: DefaultCacheCapabilities.CacheRegions;
111: }
112: }
113:
null)
115: {
116: key = key.ToLower();
117:
this._client.Get(key);
119: }
120:
null)
122: {
value = Get(key, regionName);
null)
value, regionName);
126:
null;
128: }
129:
null)
131: {
return -1;
133: }
134:
object>> GetEnumerator()
136: {
new System.NotImplementedException();
138: }
139:
null)
141: {
new System.NotImplementedException();
143: }
144:
string Name
146: {
; }
148: }
149:
null)
151: {
152: key = key.ToLower();
this._client.Remove(key);
154: }
155:
null)
157: {
value, regionName), policy);
159: }
160:
#endregion
162:
#region ICacheBuilder Members
164:
public ObjectCache GetInstance()
166: {
this;
168: }
169:
string DefaultRegionName
171: {
new NotImplementedException(); }
173: }
174:
#endregion
176: }
分布式缓存提供者Windows Server AppFabric Caching:
class AppFabricCacheProvider : ObjectCache, ICacheBuilder
2: {
null;
object();
5:
null)
7: {
8: CacheItem item = GetCacheItem(key, regionName);
null)
10: {
value, regionName), policy);
value;
13: }
14:
return item.Value;
16: }
17:
value, CacheItemPolicy policy)
19: {
value.RegionName);
null)
22: {
value, policy);
value;
25: }
26:
return item;
28: }
29:
null)
31: {
value, regionName);
new CacheItemPolicy();
34: policy.AbsoluteExpiration = absoluteExpiration;
35:
return AddOrGetExisting(item, policy);
37: }
38:
null)
40: {
null;
42: }
43:
null)
45: {
new NotImplementedException();
47: }
48:
override DefaultCacheCapabilities DefaultCacheCapabilities
50: {
51: get
52: {
return
54: DefaultCacheCapabilities.OutOfProcessProvider |
55: DefaultCacheCapabilities.AbsoluteExpirations |
56: DefaultCacheCapabilities.SlidingExpirations |
57: DefaultCacheCapabilities.CacheRegions;
58: }
59: }
60:
null)
62: {
63: key = key.ToLower();
64: CreateRegionIfNeeded();
65:
null) ?
67: CacheFactory.Get(key) :
68: CacheFactory.Get(key, regionName);
69: }
70:
null)
72: {
value = Get(key, regionName);
null)
value, regionName);
76:
null;
78: }
79:
null)
81: {
string.IsNullOrEmpty(regionName))
new NotSupportedException();
84:
return CacheFactory.GetObjectsInRegion(regionName).LongCount();
86: }
87:
object>> GetEnumerator()
89: {
new NotSupportedException();
91: }
92:
null)
94: {
string.IsNullOrEmpty(regionName))
new NotSupportedException();
97:
return CacheFactory.GetObjectsInRegion(regionName).ToDictionary(x => x.Key, x => x.Value);
99: }
100:
string Name
102: {
; }
104: }
105:
null)
107: {
108: key = key.ToLower();
109: CreateRegionIfNeeded();
110:
null) ?
112: CacheFactory.Remove(key) :
113: CacheFactory.Remove(key, regionName);
114: }
115:
null)
117: {
value, regionName), policy);
119: }
120:
void Set(CacheItem item, CacheItemPolicy policy)
122: {
null)
return;
125:
null && policy.ChangeMonitors.Count > 0)
);
128:
129: item.Key = item.Key.ToLower();
130: CreateRegionIfNeeded();
131:
null)) ?
133: policy.SlidingExpiration :
134: (policy.AbsoluteExpiration - DateTimeOffset.Now);
135:
string.IsNullOrEmpty(item.RegionName))
137: CacheFactory.Put(item.Key, item.Value, expire);
else
139: CacheFactory.Put(item.Key, item.Value, expire, item.RegionName);
140: }
141:
static DataCache CacheFactory
143: {
144: get
145: {
null)
147: {
lock (syncObj)
149: {
null)
151: {
new DataCacheFactory();
153: factory = cacheFactory.GetDefaultCache();
154: }
155: }
156: }
157:
return factory;
159: }
160: }
161:
void CreateRegionIfNeeded()
163: {
try
165: {
166: CacheFactory.CreateRegion(DefaultRegionName);
167: }
catch (DataCacheException ex)
169: {
if (!ex.ErrorCode.Equals(DataCacheErrorCode.RegionAlreadyExists))
throw ex;
172: }
173: }
174:
null)
176: {
value, regionName);
new CacheItemPolicy();
179: policy.AbsoluteExpiration = absoluteExpiration;
180:
181: Set(item, policy);
182: }
183:
string key]
185: {
186: get
187: {
return Get(key, DefaultRegionName);
189: }
190: set
191: {
null, DefaultRegionName);
193: }
194: }
195:
public ObjectCache GetInstance()
197: {
this;
199: }
200:
string DefaultRegionName
202: {
203: get
204: {
);
string.IsNullOrEmpty(defaultRegion))
207: {
;
209: }
return defaultRegion;
211: }
212: }
213: }
输出缓存对于改善性能有很大好处,在ASP.NET 4.0中可以自定义输出缓存的策略,比如把输出保存在磁盘中,外部的memcached服务中等等。甚至还可以定义一些高级规则,比如为A页面使用A输出缓存策略来把数据保存于内存中,为B页面使用B输出缓存策略来把数据保存于磁盘中。
代码例子可以参看文章http://www.buraksenyurt.com/post/AspNet-40-Custom-Cache-Provider.aspx,在web.config中配置
>
>
>
/>
>
>
>
在ASP.NET 4 的默认输出缓存策略中。所有的HTTP响应、所呈现的页面和控件缓存均使用上例所示的默认输出缓存提供程序(其中defaultProvider属性值为AspNetInternalProvider)。通过为defaultProvider指定不同的提供程序。就可以更改web应用程序的默认输出缓存提供程序。
另外,还可以针对每个用户控件和各个请求选择不同的输出缓存提供程序。要为不同的Web用户控件选择不同的输出缓存提供程序,最简便的方法是设置页面或控件指令中新增加的providerName属性,如下面的示例所示:
<%@ OutputCache Duration="60" VaryByParam="None" providerName="DiskBasedCacheProvider" %>
若要为某个HTTP请求指定不同的输出缓存提供程序,可以覆盖Global.asax文件中新增加的GetOutputCacheProviderName方法,以编程的方式指定要用于特定请求的提供程序。
参看文章:.NET 4.0新增可扩展缓存