首页 > 其他分享 >.NET4.0的可扩展缓存系统

.NET4.0的可扩展缓存系统

时间:2022-12-12 19:02:32浏览次数:75  
标签:缓存 string 扩展 NET4.0 item key null public regionName

.NET Framework中,叫做System.Runtime.Caching,这不仅是个缓存库,还是个框架,可以在上面开发自己的库。ObjectCache定义了所有缓存都要实现的通用操作。与之搭配...

.NET Framework中,叫做​​System.Runtime.Caching​​,这不仅是个缓存库,还是个框架,可以在上面开发自己的库。ObjectCache定义了所有缓存都要实现的通用操作。与之搭配的是个内存缓存实现,叫做MemoryCache。这个缓存系统的结构如下:

.NET4.0的可扩展缓存系统_缓存​​

上图大家可以看出来对应那些产品了吗?

下面我给大家介绍一个实现这样一个架构的代码示例,代码的核心就是ObjectCache:

定义一个抽象的Provider接口:

  1: public interface ICacheBuilder
2: {
3: ObjectCache GetInstance();
4: string DefaultRegionName { get; }


 

In-memory提供者的实现使用MemoryCache:

 public class MemoryCacheBuilder : ICacheBuilder
2: {
3: public MemoryCacheBuilder() { }
4:
5: public ObjectCache GetInstance()
6: {
7: return MemoryCache.Default;
8: }
9:
10: public string DefaultRegionName
11: {
12: get { return null; }
13: }
14: }


分布式缓存提供者Memcached:

 public class MemcachedCache : ObjectCache, ICacheBuilder
2: {
3: private long _lDefaultExpireTime = 3600; // default Expire Time
4: private MemcachedClient _client = null;
5: #region ICache Members
6:
7: public MemcachedCache()
8: {
9: this._client = MemcachedClientService.Instance.Client;
10: }
11:
12: public override void Set(string key, object value, System.DateTimeOffset absoluteExpiration, string regionName = null)
13: {
14: Enforce.NotNull(key, "key");
15: CacheItem item = new CacheItem(key, value, regionName);
16: CacheItemPolicy policy = new CacheItemPolicy();
17: policy.AbsoluteExpiration = absoluteExpiration;
18:
19: Set(item, policy);
20: }
21:
22: public override void Set(CacheItem item, CacheItemPolicy policy)
23: {
24: if (item == null || item.Value == null)
25: return;
26:
27: item.Key = item.Key.ToLower();
28:
29: if (policy != null && policy.ChangeMonitors != null && policy.ChangeMonitors.Count > 0)
30: throw new NotSupportedException("Change monitors are not supported");
31:
32: // max timeout in scaleout = 65535
33: TimeSpan expire = (policy.AbsoluteExpiration.Equals(null)) ?
34: policy.SlidingExpiration :
35: (policy.AbsoluteExpiration - DateTimeOffset.Now);
36:
37: double timeout = expire.TotalMinutes;
38: if (timeout > 65535)
39: timeout = 65535;
40: else if (timeout > 0 && timeout < 1)
41: timeout = 1;
42:
43: this._client.Store(Enyim.Caching.Memcached.StoreMode.Set, item.Key.ToString(), item.Value);
44:
45: }
46:
47: public override object this[string key]
48: {
49: get
50: {
51: return Get(key);
52: }
53: set
54: {
55: Set(key, value, null);
56: }
57: }
58:
59: public override object AddOrGetExisting(string key, object value, CacheItemPolicy policy, string regionName = null)
60: {
61: CacheItem item = GetCacheItem(key, regionName);
62: if (item == null)
63: {
64: Set(new CacheItem(key, value, regionName), policy);
65: return value;
66: }
67:
68: return item.Value;
69: }
70:
71: public override CacheItem AddOrGetExisting(CacheItem value, CacheItemPolicy policy)
72: {
73: CacheItem item = GetCacheItem(value.Key, value.RegionName);
74: if (item == null)
75: {
76: Set(value, policy);
77: return value;
78: }
79:
80: return item;
81: }
82:
83: public override object AddOrGetExisting(string key, object value, System.DateTimeOffset absoluteExpiration, string regionName = null)
84: {
85: CacheItem item = new CacheItem(key, value, regionName);
86: CacheItemPolicy policy = new CacheItemPolicy();
87: policy.AbsoluteExpiration = absoluteExpiration;
88:
89: return AddOrGetExisting(item, policy);
90: }
91:
92: public override bool Contains(string key, string regionName = null)
93: {
94: return false;
95: }
96:
97: public override CacheEntryChangeMonitor CreateCacheEntryChangeMonitor(System.Collections.Generic.IEnumerable<string> keys, string regionName = null)
98: {
99: throw new System.NotImplementedException();
100: }
101:
102: public override DefaultCacheCapabilities DefaultCacheCapabilities
103: {
104: get
105: {
106: return
107: DefaultCacheCapabilities.OutOfProcessProvider |
108: DefaultCacheCapabilities.AbsoluteExpirations |
109: DefaultCacheCapabilities.SlidingExpirations |
110: DefaultCacheCapabilities.CacheRegions;
111: }
112: }
113:
114: public override object Get(string key, string regionName = null)
115: {
116: key = key.ToLower();
117:
118: return this._client.Get(key);
119: }
120:
121: public override CacheItem GetCacheItem(string key, string regionName = null)
122: {
123: object value = Get(key, regionName);
124: if (value != null)
125: return new CacheItem(key, value, regionName);
126:
127: return null;
128: }
129:
130: public override long GetCount(string regionName = null)
131: {
132: return -1;
133: }
134:
135: protected override System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, object>> GetEnumerator()
136: {
137: throw new System.NotImplementedException();
138: }
139:
140: public override System.Collections.Generic.IDictionary<string, object> GetValues(System.Collections.Generic.IEnumerable<string> keys, string regionName = null)
141: {
142: throw new System.NotImplementedException();
143: }
144:
145: public override string Name
146: {
147: get { return "MemcachedProvider"; }
148: }
149:
150: public override object Remove(string key, string regionName = null)
151: {
152: key = key.ToLower();
153: return this._client.Remove(key);
154: }
155:
156: public override void Set(string key, object value, CacheItemPolicy policy, string regionName = null)
157: {
158: Set(new CacheItem(key, value, regionName), policy);
159: }
160:
161: #endregion
162:
163: #region ICacheBuilder Members
164:
165: public ObjectCache GetInstance()
166: {
167: return this;
168: }
169:
170: public string DefaultRegionName
171: {
172: get { throw new NotImplementedException(); }
173: }
174:
175: #endregion
176: }


分布式缓存提供者Windows Server AppFabric Caching:

 public class AppFabricCacheProvider : ObjectCache, ICacheBuilder
2: {
3: public static DataCache factory = null;
4: public static object syncObj = new object();
5:
6: public override object AddOrGetExisting(string key, object value, CacheItemPolicy policy, string regionName = null)
7: {
8: CacheItem item = GetCacheItem(key, regionName);
9: if (item == null)
10: {
11: Set(new CacheItem(key, value, regionName), policy);
12: return value;
13: }
14:
15: return item.Value;
16: }
17:
18: public override CacheItem AddOrGetExisting(CacheItem value, CacheItemPolicy policy)
19: {
20: CacheItem item = GetCacheItem(value.Key, value.RegionName);
21: if (item == null)
22: {
23: Set(value, policy);
24: return value;
25: }
26:
27: return item;
28: }
29:
30: public override object AddOrGetExisting(string key, object value, System.DateTimeOffset absoluteExpiration, string regionName = null)
31: {
32: CacheItem item = new CacheItem(key, value, regionName);
33: CacheItemPolicy policy = new CacheItemPolicy();
34: policy.AbsoluteExpiration = absoluteExpiration;
35:
36: return AddOrGetExisting(item, policy);
37: }
38:
39: public override bool Contains(string key, string regionName = null)
40: {
41: return Get(key, regionName) != null;
42: }
43:
44: public override CacheEntryChangeMonitor CreateCacheEntryChangeMonitor(System.Collections.Generic.IEnumerable<string> keys, string regionName = null)
45: {
46: throw new NotImplementedException();
47: }
48:
49: public override DefaultCacheCapabilities DefaultCacheCapabilities
50: {
51: get
52: {
53: return
54: DefaultCacheCapabilities.OutOfProcessProvider |
55: DefaultCacheCapabilities.AbsoluteExpirations |
56: DefaultCacheCapabilities.SlidingExpirations |
57: DefaultCacheCapabilities.CacheRegions;
58: }
59: }
60:
61: public override object Get(string key, string regionName = null)
62: {
63: key = key.ToLower();
64: CreateRegionIfNeeded();
65:
66: return (regionName == null) ?
67: CacheFactory.Get(key) :
68: CacheFactory.Get(key, regionName);
69: }
70:
71: public override CacheItem GetCacheItem(string key, string regionName = null)
72: {
73: object value = Get(key, regionName);
74: if (value != null)
75: return new CacheItem(key, value, regionName);
76:
77: return null;
78: }
79:
80: public override long GetCount(string regionName = null)
81: {
82: if (string.IsNullOrEmpty(regionName))
83: throw new NotSupportedException();
84:
85: return CacheFactory.GetObjectsInRegion(regionName).LongCount();
86: }
87:
88: protected override System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, object>> GetEnumerator()
89: {
90: throw new NotSupportedException();
91: }
92:
93: public override System.Collections.Generic.IDictionary<string, object> GetValues(System.Collections.Generic.IEnumerable<string> keys, string regionName = null)
94: {
95: if (string.IsNullOrEmpty(regionName))
96: throw new NotSupportedException();
97:
98: return CacheFactory.GetObjectsInRegion(regionName).ToDictionary(x => x.Key, x => x.Value);
99: }
100:
101: public override string Name
102: {
103: get { return "AppFabric"; }
104: }
105:
106: public override object Remove(string key, string regionName = null)
107: {
108: key = key.ToLower();
109: CreateRegionIfNeeded();
110:
111: return (regionName == null) ?
112: CacheFactory.Remove(key) :
113: CacheFactory.Remove(key, regionName);
114: }
115:
116: public override void Set(string key, object value, CacheItemPolicy policy, string regionName = null)
117: {
118: Set(new CacheItem(key, value, regionName), policy);
119: }
120:
121: public override void Set(CacheItem item, CacheItemPolicy policy)
122: {
123: if (item == null || item.Value == null)
124: return;
125:
126: if (policy != null && policy.ChangeMonitors != null && policy.ChangeMonitors.Count > 0)
127: throw new NotSupportedException("Change monitors are not supported");
128:
129: item.Key = item.Key.ToLower();
130: CreateRegionIfNeeded();
131:
132: TimeSpan expire = (policy.AbsoluteExpiration.Equals(null)) ?
133: policy.SlidingExpiration :
134: (policy.AbsoluteExpiration - DateTimeOffset.Now);
135:
136: if (string.IsNullOrEmpty(item.RegionName))
137: CacheFactory.Put(item.Key, item.Value, expire);
138: else
139: CacheFactory.Put(item.Key, item.Value, expire, item.RegionName);
140: }
141:
142: private static DataCache CacheFactory
143: {
144: get
145: {
146: if (factory == null)
147: {
148: lock (syncObj)
149: {
150: if (factory == null)
151: {
152: DataCacheFactory cacheFactory = new DataCacheFactory();
153: factory = cacheFactory.GetDefaultCache();
154: }
155: }
156: }
157:
158: return factory;
159: }
160: }
161:
162: private void CreateRegionIfNeeded()
163: {
164: try
165: {
166: CacheFactory.CreateRegion(DefaultRegionName);
167: }
168: catch (DataCacheException ex)
169: {
170: if (!ex.ErrorCode.Equals(DataCacheErrorCode.RegionAlreadyExists))
171: throw ex;
172: }
173: }
174:
175: public override void Set(string key, object value, System.DateTimeOffset absoluteExpiration, string regionName = null)
176: {
177: CacheItem item = new CacheItem(key, value, regionName);
178: CacheItemPolicy policy = new CacheItemPolicy();
179: policy.AbsoluteExpiration = absoluteExpiration;
180:
181: Set(item, policy);
182: }
183:
184: public override object this[string key]
185: {
186: get
187: {
188: return Get(key, DefaultRegionName);
189: }
190: set
191: {
192: Set(key, value, null, DefaultRegionName);
193: }
194: }
195:
196: public ObjectCache GetInstance()
197: {
198: return this;
199: }
200:
201: public string DefaultRegionName
202: {
203: get
204: {
205: string defaultRegion= FrameworkConfiguationManager.GetConfiguration().GetAppVariable("AppFabricCacheDefaultRegion");
206: if (string.IsNullOrEmpty(defaultRegion))
207: {
208: defaultRegion = "Default";
209: }
210: return defaultRegion;
211: }
212: }
213: }


输出缓存对于改善性能有很大好处,在ASP.NET 4.0中可以自定义输出缓存的策略,比如把输出保存在磁盘中,外部的memcached服务中等等。甚至还可以定义一些高级规则,比如为A页面使用A输出缓存策略来把数据保存于内存中,为B页面使用B输出缓存策略来把数据保存于磁盘中。​​.NET4.0的可扩展缓存系统_缓存_02

代码例子可以参看文章​​http://www.buraksenyurt.com/post/AspNet-40-Custom-Cache-Provider.aspx​​,在web.config中配置

 <caching>
2: <outputCache defaultProvider="AspNetInternalProvider">
3: <providers>
4: <add name="DiskBasedCacheProvider" type="CustomCaching.DiskCacheProvider,CustomCaching"/>
5: </providers>
6: </outputCache>
7: </caching>


在ASP.NET 4 的默认输出缓存策略中。所有的HTTP响应、所呈现的页面和控件缓存均使用上例所示的默认输出缓存提供程序(其中defaultProvider属性值为AspNetInternalProvider)。通过为defaultProvider指定不同的提供程序。就可以更改web应用程序的默认输出缓存提供程序。

另外,还可以针对每个用户控件和各个请求选择不同的输出缓存提供程序。要为不同的Web用户控件选择不同的输出缓存提供程序,最简便的方法是设置页面或控件指令中新增加的providerName属性,如下面的示例所示:

<%@ OutputCache Duration="60" VaryByParam="None"  providerName="DiskBasedCacheProvider" %>

若要为某个HTTP请求指定不同的输出缓存提供程序,可以覆盖Global.asax文件中新增加的GetOutputCacheProviderName方法,以编程的方式指定要用于特定请求的提供程序。




标签:缓存,string,扩展,NET4.0,item,key,null,public,regionName
From: https://blog.51cto.com/shanyou/5931302

相关文章

  • modbus扩展IO模块支持模拟量输入
    一、产品介绍1.1、简介DAM模块可实现2/4路模拟量和2/4路热电阻PT100/PT1000温度信号测量。模块通讯接口为RS-485口,MODBUS-RTU通讯协议。DC9~36V电源供电。DAM模......
  • 【FAQ】HarmonyOS JavaUI中使用terminate()后重新打开AbilitySlice页面存在缓存
    【前言】同一个Ability下的两个不同的AbilitySlice,官方给的JavaUI中是通过present跳转AbilitySlice,使用AbilitySlice.terminate方法关闭Slice,具体可以参考官方给的示例代码......
  • Ansible最佳实践之 AWX 启用facts缓存和模板问卷调查
    写在前面分享一些AWX启用facts缓存和模板问卷调查的笔记博文内容涉及:启动facts缓存相关配置Demo启用模板调查来设置变量demo食用方式:需要了解Ansible理解不足小伙伴......
  • gradle缓存清除
    强制清除gradle的缓存问题:有时在开发中我们会上传一些开发jar到远程仓库,当我们打包时版本号不变时有时候我们跟新不到新的jar问题分析:这个问题一般是因为gradle的缓存机制......
  • 动态组件-缓存怎么做
    设置动态组件需要添加component组件定义形式<component:is='给定的组件名称'/>组件缓存:定义keep-alive组件即可;如果组件缓存了会有两个钩子钩子可以使用:activated:当它......
  • 扩展KMP算法
      前文已经介绍了经典的​​KMP算法​​​,本文继续介绍KMP算法的扩展,即扩展KMP算法。  问题定义:给定两个字符串S和T(长度分别为n和m),下标从0开始,定义extend[i]等于S[i]......
  • 高速缓存
    局部性原理(locality)时间局部性与空间局部性局部性通常有两种不同的形式,时间局部性(temporallocality)和空间局部性(spatiallocality)。在一个具有良好时间局部性的程......
  • JS实现决策报表缓存最后一次查询条件
    问题描述决策报表在打开时希望参数控件的值可以默认是上一次页面关闭前最后一次查询所选择的值。解决方案每次点击查询后将参数值保存到浏览器缓存中(适用于控件在参数......
  • P5410 【模板】扩展 KMP(Z 函数)
    题目链接P5410【模板】扩展KMP(Z函数)【模板】扩展KMP(Z函数)题目描述给定两个字符串\(a,b\),你要求出两个数组:\(b\)的\(z\)函数数组\(z\),即\(b\)与\(b\)的......
  • 模板链表类的扩展(QListEx<T>)
    以前写的链表都是比较简单的,插入节点是在头节点上,所以循环链表时都是从最后一个数据往前找的,给人的感觉是倒着的,今天写一个在链表尾部插入数据1。链表节点类的定义/链......