ASP.NET Core Cache

Posted by Max Lin on 2023-02-11

快取主要是將資料暫存於記憶體,方面日後調用時能有更好的回應速度以及重用性,同時也減少對資源的消耗(如:網路、Disk I/O)。

舉一個適用場景:

當查詢的資料 不常變更 時,如:歷史資料,其多次查詢大多結果都相同,這時就很適合把該資料存進快取,當查詢時就直接從快取獲得資料並回傳給使用方而不必透過資料庫存取,也印證了開頭提到的特點。

於 Program.cs 注入 MemoryCache

如下:

builder.Services.AddMemoryCache();

在建構式傳入 IMemoryCache 實體

如下:

private readonly IMemoryCache _memoryCache;

public MemoryCacheController(IMemoryCache memoryCache)
{
    _memoryCache = memoryCache;
}

新增快取資料

※ 如新增重複 key 會直接覆蓋舊 value

// 依 id 儲存資料於快取
_memoryCache.Set(info.Id, info);

刪除快取資料

// 依 id 刪除快取資料
_memoryCache.Remove(userId);

取得快取資料

分幾種方式:

  • 單純 get
var info = _memoryCache.Get<UserInfo>(userId);
if (info == null)
{
    // 找不到的情況
    throw KeyNotFoundException();
}

return info;
  • TryGetValue
if (_memoryCache.TryGetValue<UserInfo>(userId, out var info) == false)
{
    // 找不到的情況
    throw KeyNotFoundException();
}
return info;
  • GetOrCreate (個人較常用)

此方式支援同步(GetOrCreate)和非同步(GetOrCreateAsync)

// 找到就直接回傳,找不到就去 GetUserInfoFromDb 取
var info = _memoryCache.GetOrCreate(userId, (entry) =>
{
    return GetUserInfoFromDb();
});

return info;

設定快取過期時間(TTL)

過期機制分為:

  • Absolute:設定的過期時間到了將直接刪除
  • Sliding:在設定的過期時間內,如沒有存取將會 刪除,若有存取則會 重置 過期時間
var info = _memoryCache.GetOrCreate(userId, (entry) =>
{
    // Set AbsoluteExpiration for 1 day
    entry.AbsoluteExpiration = DateTimeOffset.Now.AddDays(1);
    // Set SlidingExpiration for 1 hour
    entry.SlidingExpiration =  TimeSpan.FromHours(1);

    return GetUserInfoFromDb();
});

return info;

參考:

範例原始碼