.net core 下的簡單二級快取
阿新 • • 發佈:2018-11-16
.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);
}
}
結尾
優點:簡單易用
缺點:缺失很多快取的特性,並且對於快取的大小等都無限制。濫用很可能導致本地記憶體暴增。