想提升站點的性能,於是增加了緩存,但是站點不會太大,於是不會到分布式memcached的緩存和redis這個nosql庫,於是自己封裝了.NET內置的緩存組件
原先使用System.Web.Caching.Cache,但是asp.net會在System.Web.Caching.Cache緩存頁面等數據,於是替換了System.Web.Caching.Cache為MemoryCache。
而在使用MemoryCache的時候,重新啟動網站會丟失緩存,於是加了自己的擴展,將緩存序列化存放在文件內,在緩存丟的時候從文件內獲取緩存,做了簡易的擴展。(現在應用在我的Cactus里面)
using System; using System.Collections; using System.Web; using System.Text; using System.IO; using System.Runtime.Caching; using System.Diagnostics; using System.Runtime.Serialization.Formatters.Binary; using System.Configuration; using System.Collections.Generic; namespace Cactus.Common { /// <summary> /// 緩存對象數據結構 /// </summary> [Serializable()] public class CacheData{ public object Value { get;set;} public DateTime CreateTime { get; set; } public DateTimeOffset AbsoluteExpiration { get; set; } public DateTime FailureTime { get { if (AbsoluteExpiration == System.Runtime.Caching.ObjectCache.InfiniteAbsoluteExpiration) { return AbsoluteExpiration.DateTime; } else { return CreateTime.AddTicks(AbsoluteExpiration.Ticks); } } } public CacheItemPriority Priority { get; set; } } /// <summary> /// 緩存處理類(MemoryCache) /// </summary> public class CacheHelper { //在應用程序的同級目錄(主要防止外部訪問) public static string filePath = Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.ConnectionStrings["filecache"].ConnectionString); //文件擴展名 public static string fileExt = ".cache"; /// <summary> /// 獲取數據緩存 /// </summary> /// <param name="cacheKey">鍵</param> public static object GetCache(string cacheKey) { //System.Web.Caching.Cache objCache = HttpRuntime.Cache; //return objCache[cacheKey]; long i=System.Runtime.Caching.MemoryCache.Default.GetCount(); CacheItem objCache=System.Runtime.Caching.MemoryCache.Default.GetCacheItem(cacheKey); if (objCache == null) { string _filepath = filePath + cacheKey + fileExt; if (File.Exists(_filepath)) { FileStream _file = File.OpenRead(_filepath); if (_file.CanRead) { Debug.WriteLine("緩存反序列化獲取數據:" + cacheKey); object obj = CacheHelper.BinaryDeSerialize(_file); CacheData _data = (CacheData)obj; if (_data != null) { //判斷是否過期 if (_data.FailureTime >= DateTime.Now) { //將數據添加到內存 CacheHelper.SetCacheToMemory(cacheKey, _data); return _data.Value; } else { Debug.WriteLine("數據過期:" + cacheKey); File.Delete(_filepath); //數據過期 return null; } } else { return null; } } else { return null; } } else { return null; } } else { CacheData _data = (CacheData)objCache.Value; return _data.Value; } } /// <summary> /// 內存緩存數 /// </summary> /// <returns></returns> public static object GetCacheCount() { return System.Runtime.Caching.MemoryCache.Default.GetCount(); } /// <summary> /// 文件緩存數 /// </summary> /// <returns></returns> public static object GetFileCacheCount() { DirectoryInfo di = new DirectoryInfo(filePath); return di.GetFiles().Length; } /// <summary> /// 設置數據緩存 /// </summary> public static bool SetCache(string cacheKey, object objObject, CacheItemPolicy policy) { //System.Web.Caching.Cache objCache = HttpRuntime.Cache; //objCache.Insert(cacheKey, objObject); string _filepath = filePath + cacheKey + fileExt; if (Directory.Exists(filePath)==false) { Directory.CreateDirectory(filePath); } //設置緩存數據的相關參數 CacheData data = new CacheData() { Value = objObject, CreateTime = DateTime.Now, AbsoluteExpiration = policy.AbsoluteExpiration, Priority = policy.Priority }; CacheItem objCache = new CacheItem(cacheKey, data); FileStream stream = null; if (File.Exists(_filepath) == false) { stream = new FileStream(_filepath, FileMode.CreateNew, FileAccess.Write, FileShare.Write); } else { stream = new FileStream(_filepath, FileMode.Create, FileAccess.Write, FileShare.Write); } Debug.WriteLine("緩存序列化設置數據:" + cacheKey); CacheHelper.BinarySerialize(stream, data); return System.Runtime.Caching.MemoryCache.Default.Add(objCache, policy); } public static bool SetCacheToMemory(string cacheKey, CacheData data) { CacheItemPolicy policy = new CacheItemPolicy(); CacheItem objCache = new CacheItem(cacheKey, data); policy.AbsoluteExpiration = data.AbsoluteExpiration; policy.Priority = CacheItemPriority.NotRemovable; return System.Runtime.Caching.MemoryCache.Default.Add(objCache, policy); } public static bool SetCache(string cacheKey, object objObject, DateTimeOffset AbsoluteExpiration) { //System.Web.Caching.Cache objCache = HttpRuntime.Cache; //objCache.Insert(cacheKey, objObject); CacheItemPolicy _priority = new CacheItemPolicy(); _priority.Priority = CacheItemPriority.NotRemovable; _priority.AbsoluteExpiration = AbsoluteExpiration; return SetCache(cacheKey, objObject, _priority); } public static bool SetCache(string cacheKey, object objObject, CacheItemPriority priority) { //System.Web.Caching.Cache objCache = HttpRuntime.Cache; //objCache.Insert(cacheKey, objObject); CacheItemPolicy _priority = new CacheItemPolicy(); _priority.Priority = priority; _priority.AbsoluteExpiration = System.Runtime.Caching.ObjectCache.InfiniteAbsoluteExpiration; return SetCache(cacheKey, objObject, _priority); } /// <summary> /// 設置數據緩存 /// </summary> public static bool SetCache(string cacheKey, object objObject) { //System.Web.Caching.Cache objCache = HttpRuntime.Cache; //objCache.Insert(cacheKey, objObject, null, DateTime.MaxValue, timeout, System.Web.Caching.CacheItemPriority.NotRemovable, null); return CacheHelper.SetCache(cacheKey, objObject, System.Runtime.Caching.CacheItemPriority.NotRemovable); } /// <summary> /// 移除指定數據緩存 /// </summary> public static void RemoveCache(string cacheKey) { //System.Web.Caching.Cache cache = HttpRuntime.Cache; //cache.Remove(cacheKey); System.Runtime.Caching.MemoryCache.Default.Remove(cacheKey); string _filepath = filePath + cacheKey + fileExt; File.Delete(_filepath); } /// <summary> /// 移除全部緩存 /// </summary> public static void RemoveAllCache() { //System.Web.Caching.Cache cache = HttpRuntime.Cache; //IDictionaryEnumerator cacheEnum = cache.GetEnumerator(); //while (cacheEnum.MoveNext()) //{ // cache.Remove(cacheEnum.Key.ToString()); //} MemoryCache _cache = System.Runtime.Caching.MemoryCache.Default; foreach (var _c in _cache.GetValues(null)) { _cache.Remove(_c.Key); } DirectoryInfo di = new DirectoryInfo(filePath); di.Delete(true); } /// <summary> /// 清除指定緩存 /// </summary> /// <param name="type">1:內存 2:文件</param> public static void RemoveAllCache(int type) { if (type == 1) { MemoryCache _cache = System.Runtime.Caching.MemoryCache.Default; foreach (var _c in _cache.GetValues(null)) { _cache.Remove(_c.Key); } } else if (type == 2) { DirectoryInfo di = new DirectoryInfo(filePath); di.Delete(true); } } #region 流序列化 public static void BinarySerialize(Stream stream, object obj) { try { stream.Seek(0, SeekOrigin.Begin); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, obj); } catch (Exception e) { IOHelper.WriteDebug(e); } finally { //stream.Close(); stream.Dispose(); } } public static object BinaryDeSerialize(Stream stream) { object obj = null; stream.Seek(0, SeekOrigin.Begin); try { BinaryFormatter formatter = new BinaryFormatter(); obj = formatter.Deserialize(stream); } catch (Exception e) { IOHelper.WriteDebug(e); } finally { //stream.Close(); stream.Dispose(); } return obj; } #endregion } }