您好,登錄后才能下訂單哦!
小編給大家分享一下.NET 4.0可擴(kuò)展緩存框架的示例分析,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
.NET Framework中,叫做System.Runtime.Caching,這不僅是個(gè)緩存庫,還是個(gè)框架,可以在上面開發(fā)自己的庫。ObjectCache定義了所有緩存都要實(shí)現(xiàn)的通用操作。與之搭配的是個(gè)內(nèi)存緩存實(shí)現(xiàn),叫做MemoryCache。這個(gè)緩存系統(tǒng)的結(jié)構(gòu)如下:
上圖大家可以看出來對(duì)應(yīng)那些產(chǎn)品了嗎?
下面我給大家介紹一個(gè)實(shí)現(xiàn)這樣一個(gè)架構(gòu)的代碼示例,代碼的核心就是ObjectCache:
定義一個(gè)抽象的Provider接口:
public interface ICacheBuilder { ObjectCache GetInstance(); string DefaultRegionName { get; } }
In-memory提供者的實(shí)現(xiàn)使用MemoryCache:
public class MemoryCacheBuilder : ICacheBuilder { public MemoryCacheBuilder() { } public ObjectCache GetInstance() { return MemoryCache.Default; } public string DefaultRegionName { get { return null; } } }
分布式緩存提供者M(jìn)emcached:
public class MemcachedCache : ObjectCache, ICacheBuilder { private long _lDefaultExpireTime = 3600; // default Expire Time private MemcachedClient _client = null; #region ICache Members public MemcachedCache() { this._client = MemcachedClientService.Instance.Client; } public override void Set(string key, object value, System.DateTimeOffset absoluteExpiration, string regionName = null) { Enforce.NotNull(key, "key"); CacheItem item = new CacheItem(key, value, regionName); CacheItemPolicy policy = new CacheItemPolicy(); policy.AbsoluteExpiration = absoluteExpiration; Set(item, policy); } public override void Set(CacheItem item, CacheItemPolicy policy) { if (item == null || item.Value == null) return; item.Key = item.Key.ToLower(); if (policy != null && policy.ChangeMonitors != null && policy.ChangeMonitors.Count > 0) throw new NotSupportedException("Change monitors are not supported"); // max timeout in scaleout = 65535 TimeSpan expire = (policy.AbsoluteExpiration.Equals(null)) ? policy.SlidingExpiration : (policy.AbsoluteExpiration - DateTimeOffset.Now); double timeout = expire.TotalMinutes; if (timeout > 65535) timeout = 65535; else if (timeout > 0 && timeout < 1) timeout = 1; this._client.Store(Enyim.Caching.Memcached.StoreMode.Set, item.Key.ToString(), item.Value); } public override object this[string key] { get { return Get(key); } set { Set(key, value, null); } } public override object AddOrGetExisting(string key, object value, CacheItemPolicy policy, string regionName = null) { CacheItem item = GetCacheItem(key, regionName); if (item == null) { Set(new CacheItem(key, value, regionName), policy); return value; } return item.Value; } public override CacheItem AddOrGetExisting(CacheItem value, CacheItemPolicy policy) { CacheItem item = GetCacheItem(value.Key, value.RegionName); if (item == null) { Set(value, policy); return value; } return item; } public override object AddOrGetExisting(string key, object value, System.DateTimeOffset absoluteExpiration, string regionName = null) { CacheItem item = new CacheItem(key, value, regionName); CacheItemPolicy policy = new CacheItemPolicy(); policy.AbsoluteExpiration = absoluteExpiration; return AddOrGetExisting(item, policy); } public override bool Contains(string key, string regionName = null) { return false; } public override CacheEntryChangeMonitor CreateCacheEntryChangeMonitor(System.Collections.Generic.IEnumerable<string> keys, string regionName = null) { throw new System.NotImplementedException(); } public override DefaultCacheCapabilities DefaultCacheCapabilities { get { return DefaultCacheCapabilities.OutOfProcessProvider | DefaultCacheCapabilities.AbsoluteExpirations | DefaultCacheCapabilities.SlidingExpirations | DefaultCacheCapabilities.CacheRegions; } } public override object Get(string key, string regionName = null) { key = key.ToLower(); return this._client.Get(key); } public override CacheItem GetCacheItem(string key, string regionName = null) { object value = Get(key, regionName); if (value != null) return new CacheItem(key, value, regionName); return null; } public override long GetCount(string regionName = null) { return -1; } protected override System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, object>> GetEnumerator() { throw new System.NotImplementedException(); } public override System.Collections.Generic.IDictionary<string, object> GetValues(System.Collections.Generic.IEnumerable<string> keys, string regionName = null) { throw new System.NotImplementedException(); } public override string Name { get { return "MemcachedProvider"; } } public override object Remove(string key, string regionName = null) { key = key.ToLower(); return this._client.Remove(key); } public override void Set(string key, object value, CacheItemPolicy policy, string regionName = null) { Set(new CacheItem(key, value, regionName), policy); } #endregion #region ICacheBuilder Members public ObjectCache GetInstance() { return this; } public string DefaultRegionName { get { throw new NotImplementedException(); } } #endregion }
分布式緩存提供者Windows Server AppFabric Caching:
public class AppFabricCacheProvider : ObjectCache, ICacheBuilder { public static DataCache factory = null; public static object syncObj = new object(); public override object AddOrGetExisting(string key, object value, CacheItemPolicy policy, string regionName = null) { CacheItem item = GetCacheItem(key, regionName); if (item == null) { Set(new CacheItem(key, value, regionName), policy); return value; } return item.Value; } public override CacheItem AddOrGetExisting(CacheItem value, CacheItemPolicy policy) { CacheItem item = GetCacheItem(value.Key, value.RegionName); if (item == null) { Set(value, policy); return value; } return item; } public override object AddOrGetExisting(string key, object value, System.DateTimeOffset absoluteExpiration, string regionName = null) { CacheItem item = new CacheItem(key, value, regionName); CacheItemPolicy policy = new CacheItemPolicy(); policy.AbsoluteExpiration = absoluteExpiration; return AddOrGetExisting(item, policy); } public override bool Contains(string key, string regionName = null) { return Get(key, regionName) != null; } public override CacheEntryChangeMonitor CreateCacheEntryChangeMonitor(System.Collections.Generic.IEnumerable<string> keys, string regionName = null) { throw new NotImplementedException(); } public override DefaultCacheCapabilities DefaultCacheCapabilities { get { return DefaultCacheCapabilities.OutOfProcessProvider | DefaultCacheCapabilities.AbsoluteExpirations | DefaultCacheCapabilities.SlidingExpirations | DefaultCacheCapabilities.CacheRegions; } } public override object Get(string key, string regionName = null) { key = key.ToLower(); CreateRegionIfNeeded(); return (regionName == null) ? CacheFactory.Get(key) : CacheFactory.Get(key, regionName); } public override CacheItem GetCacheItem(string key, string regionName = null) { object value = Get(key, regionName); if (value != null) return new CacheItem(key, value, regionName); return null; } public override long GetCount(string regionName = null) { if (string.IsNullOrEmpty(regionName)) throw new NotSupportedException(); return CacheFactory.GetObjectsInRegion(regionName).LongCount(); } protected override System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, object>> GetEnumerator() { throw new NotSupportedException(); } public override System.Collections.Generic.IDictionary<string, object> GetValues(System.Collections.Generic.IEnumerable<string> keys, string regionName = null) { if (string.IsNullOrEmpty(regionName)) throw new NotSupportedException(); return CacheFactory.GetObjectsInRegion(regionName).ToDictionary(x => x.Key, x => x.Value); } public override string Name { get { return "AppFabric"; } } public override object Remove(string key, string regionName = null) { key = key.ToLower(); CreateRegionIfNeeded(); return (regionName == null) ? CacheFactory.Remove(key) : CacheFactory.Remove(key, regionName); } public override void Set(string key, object value, CacheItemPolicy policy, string regionName = null) { Set(new CacheItem(key, value, regionName), policy); } public override void Set(CacheItem item, CacheItemPolicy policy) { if (item == null || item.Value == null) return; if (policy != null && policy.ChangeMonitors != null && policy.ChangeMonitors.Count > 0) throw new NotSupportedException("Change monitors are not supported"); item.Key = item.Key.ToLower(); CreateRegionIfNeeded(); TimeSpan expire = (policy.AbsoluteExpiration.Equals(null)) ? policy.SlidingExpiration : (policy.AbsoluteExpiration - DateTimeOffset.Now); if (string.IsNullOrEmpty(item.RegionName)) CacheFactory.Put(item.Key, item.Value, expire); else CacheFactory.Put(item.Key, item.Value, expire, item.RegionName); } private static DataCache CacheFactory { get { if (factory == null) { lock (syncObj) { if (factory == null) { DataCacheFactory cacheFactory = new DataCacheFactory(); factory = cacheFactory.GetDefaultCache(); } } } return factory; } } private void CreateRegionIfNeeded() 163: { try { CacheFactory.CreateRegion(DefaultRegionName); } catch (DataCacheException ex) { if (!ex.ErrorCode.Equals(DataCacheErrorCode.RegionAlreadyExists)) throw ex; } } public override void Set(string key, object value, System.DateTimeOffset absoluteExpiration, string regionName = null) { CacheItem item = new CacheItem(key, value, regionName); CacheItemPolicy policy = new CacheItemPolicy(); policy.AbsoluteExpiration = absoluteExpiration; Set(item, policy); } public override object this[string key] { get { return Get(key, DefaultRegionName); } set { Set(key, value, null, DefaultRegionName); } } public ObjectCache GetInstance() { return this; } public string DefaultRegionName { get { string defaultRegion= FrameworkConfiguationManager.GetConfiguration().GetAppVariable("AppFabricCacheDefaultRegion"); if (string.IsNullOrEmpty(defaultRegion)) { defaultRegion = "Default"; } return defaultRegion; } } }
輸出緩存對(duì)于改善性能有很大好處,在ASP.NET 4.0中可以自定義輸出緩存的策略,比如把輸出保存在磁盤中,外部的memcached服務(wù)中等等。甚至還可以定義一些高級(jí)規(guī)則,比如為A頁面使用A輸出緩存策略來把數(shù)據(jù)保存于內(nèi)存中,為B頁面使用B輸出緩存策略來把數(shù)據(jù)保存于磁盤中。
代碼例子可以參看文章http://www.buraksenyurt.com/post/AspNet-40-Custom-Cache-Provider.aspx,在web.config中配置
<caching> <outputCache defaultProvider="AspNetInternalProvider"> <providers> <add name="DiskBasedCacheProvider" type="CustomCaching.DiskCacheProvider,CustomCaching"/> </providers> </outputCache> </caching>
在ASP.NET 4 的默認(rèn)輸出緩存策略中。所有的HTTP響應(yīng)、所呈現(xiàn)的頁面和控件緩存均使用上例所示的默認(rèn)輸出緩存提供程序(其中defaultProvider屬性值為AspNetInternalProvider)。通過為defaultProvider指定不同的提供程序。就可以更改web應(yīng)用程序的默認(rèn)輸出緩存提供程序。
另外,還可以針對(duì)每個(gè)用戶控件和各個(gè)請(qǐng)求選擇不同的輸出緩存提供程序。要為不同的Web用戶控件選擇不同的輸出緩存提供程序,最簡便的方法是設(shè)置頁面或控件指令中新增加的providerName屬性,如下面的示例所示:
<%@ OutputCache Duration="60" VaryByParam="None" providerName="DiskBasedCacheProvider" %>
若要為某個(gè)HTTP請(qǐng)求指定不同的輸出緩存提供程序,可以覆蓋Global.asax文件中新增加的GetOutputCacheProviderName方法,以編程的方式指定要用于特定請(qǐng)求的提供程序。
看完了這篇文章,相信你對(duì)“.NET 4.0可擴(kuò)展緩存框架的示例分析”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。