前言
當需要重複抓取資料時,而資料量又少且不常變動,造成效能降低,此時可以使用Memory Cache,將資料暫存記憶體中改善Web Application效能
如何設計快取
使用快取,需要注意的是資料一致性的問題,要如何確保在資料一致前提下怎麼設計快取能夠使用最長的快取 。
-
Set - 快取存在時會直接覆寫
-
Cache[key]=value - 快取已存在時一樣會直接覆寫,但無法設定清除快取機制
-
Add - 快取已存在時不會覆寫,會回傳false結果告知失敗
清除快取的機制 (CacheItemPolicy)
清除快取資料能夠分為兩種:
-
時間到期(Expiration) :
-
絕對時間 (AbsoluteExpiration):DateTimeOffset 時間超過設定的時間後,就會清除快取。
-
時間空隔(SlidingExpiration) : TimeSpan 快取資料多久的時間沒有被使用,就會清除快取。
-
-
資料變動 (ChangeMonitor)
-
實體檔案變動 (HostFileChangeMonitor):檔案內容更動時就會清除快取。
-
資料庫變動(SqlChangeMonitor):當資料庫指令結果有不同就會清除快取。
-
使用的擴充方法為:
Set(IMemoryCache, Object, TItem, MemoryCacheEntryOptions)
TryGetValue(Object, Object)
實作並搭配DI使用
在Startup裡的ConfigureServices裡加上程式碼,設定完即DI注入使用。
public void ConfigureServices(IServiceCollection services)
{
services.AddMemoryCache(); // 這一行就可以了
services.AddMvc();
}
使用IMemoryCache為注入的對象
public class AccountController : Controller
{
private readonly IMemoryCache memoryCache;
public AccountController(IMemoryCache _memoryCache)
{
this.memoryCache = _memoryCache;
}
}
範例1 - 絕對時間測試(AbsoluteExpiration)
public IEnumerable<TimetableEnum> GetTimetableEnums()
{
IEnumerable<TimetableEnum> timetableEnumDtos;
// 檢查cache是否有時刻表,TryGetValue回傳的是bool,
// 在快取查不到資料時回傳false,所以這裡要使用反向進入if執行cache
if (!_cache.TryGetValue("TimetableEnum", out timetableEnumDtos))
{
//拿取火車時刻表資料
crmLogEnumDtos = _InfoDbRepo.GetTimetableEnum();
//將資料儲存到快取中,並且設定一天的時間到了會清除快取的資料
_cache.Set(
"TimetableEnum",
timetableEnumDtos,
DateTimeOffset.Now.AddDays(1)
);
}
return timetableEnumDtos;
}
範例2 - 時間到了會清除快取時間空隔測試(SlidingExpiration)
public IEnumerable<TimetableEnum> GetTimetableEnums()
{
IEnumerable<TimetableEnum> timetableEnumDtos;
if (!_cache.TryGetValue("TimetableEnum", out timetableEnumDtos))
{
crmLogEnumDtos = _InfoDbRepo.GetTimetableEnum();
//將資料儲存到快取中,並且設定15分鐘內如果沒有使用到這筆快取資料則會清除快取的資料
_cache.Set("TimetableEnum", timetableEnumDtos, TimeSpan.FromMinutes(15));
}
return timetableEnumDtos;
}
結尾
如果想了解更多可以至官方的快取說明 。