1. 程式人生 > >.net core 下的簡單二級快取

.net core 下的簡單二級快取

.net core 下的簡單二級快取

為什麼寫輪子

.net core 下的二級快取做的已經足夠好了,此次編寫輪子是因為需要在 .net core 和 .net Framework 4.6 兩個框架中共用該類,因此沒辦法直接使用MemoryCache

快取思路

這裡快取採用靜態變數儲存,為了執行緒安全,採用如下程式碼定義:

 private static  ConcurrentDictionary<
string, object> _dict = new ConcurrentDictionary<string, object>();

有了詞典就比較好辦了,需要二級快取時就儲存在該詞典類,如果訪問過期就幹掉它。如果沒有在詞典中查詢到,就到Redis快取中拉取,並放入詞典快取,過期時間半分鐘。

//從Redis拉取,這裡沒有封裝redis鍵的過期時間,因此用**帶過期時間的快取類**簡單處理,避免其他程序過於頻繁的拉取Redis
var cache = Cache.CacheManager.GetCache();
var val = cache?.Get<CacheClass<
T>>(key) ; if (val != null) { _dict.TryAdd(key, val); } return val?.Value;

帶過期時間的快取類

自己管理過期

	/// <summary>
    /// 帶過期時間的快取類
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class CacheClass<T> where T:class
    {
        /// <summary>
        /// 快取值
/// </summary> public T Value { private set; get; } /// <summary> /// 絕對過期時間 /// </summary> public DateTime ExpireDate {private set;get;} /// <summary> /// 判斷是否過期,true-過期 /// </summary> /// <returns></returns> public bool IsExpire() { return (ExpireDate < DateTime.Now); } /// <summary> /// 構造 /// </summary> /// <param name="obj"></param> /// <param name="expireDate">絕對過期時間</param> public CacheClass(T obj, DateTime? expireDate = null) { this.Value = obj; if (!expireDate.HasValue) { ExpireDate = DateTime.Now + new TimeSpan(0, 10, 0); } else { ExpireDate = expireDate.Value; } } }

完整的Get和Set方法

public static T Get<T>(string key) where T : class
 {
     object obj ;
     if (_dict.TryGetValue(key, out obj))
     {
         var cc = (CacheClass<T>)obj;
         if (cc.IsExpire())
         {
             _dict.TryRemove(key, out obj);
         }
         else
         {
             return cc.Value;
         }
     }

     //從redis中取值
     var cache = Cache.CacheManager.GetCache();
     var val = cache?.Get<CacheClass<T>>(key) ;
     if (val != null)
     {
         _dict.TryAdd(key, val);
     }
     else
     {
         _dict.TryRemove(key,out obj);
     }
     return val?.Value;
 }

 /// <summary>
 /// 設定快取
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="key"></param>
 /// <param name="obj"></param>
 /// <param name="expireDate"></param>
 public static void Set<T>(string key, T obj, DateTime? expireDate = null) where T : class
 {
     var cc = new CacheClass<T>(obj, expireDate);
     if (!cc.IsExpire())
     {
         _dict.TryAdd(key, cc);
         var cache = Cache.CacheManager.GetCache();
         cache?.Set<CacheClass<T>>(key, cc, cc.ExpireDate);
     }
 }

結尾

優點:簡單易用
缺點:缺失很多快取的特性,並且對於快取的大小等都無限制。濫用很可能導致本地記憶體暴增。

引用連結

  1. 口袋程式碼倉庫
  2. 線上計算器
  3. 本節原始碼:github