幾乎在全部的應用程序中,緩存都是一個永恆的話題,恰當的使用緩存能夠有效提升應用程序的性能;在某些業務場景下,使用緩存依賴會有很好的體驗;在 Asp.Net Core 中,支持了多種緩存組件,這其中最基礎也最易用的當屬 IMemoryCache,該接口表示其存儲依賴於託管程序服務器的內存,下面要介紹的內容就是基於 IMemoryCache 的緩存依賴。git
Asp.Net Core 內部實現了一個繼承自 IMemoryCache 接口的類 MemoryCache
這幾乎已成慣例,一旦某個接口被列入 SDK 中,其必然包含了一個默認實現github
在 Asp.Net Core 中要使用 IMemoryCache 很是簡單,只須要在 Startup 的 ConfigureServices 方法加入一句代碼 services.AddMemoryCache() 便可api
public void ConfigureServices(IServiceCollection services) { services.AddMemoryCache(); ... }
[Route("api/[controller]")] [ApiController] public class HomeController : ControllerBase { private IMemoryCache cache; public HomeController(IMemoryCache cache) { this.cache = cache; } [HttpGet] public ActionResult<IEnumerable<string>> Get() { cache.Set("userId", "0001"); return new string[] { "value1", "value2" }; } [HttpGet("{id}")] public ActionResult<string> Get(int id) { return cache.Get<string>("userId"); } }
上面的代碼表示在 HomeController 控制器的構造方法中使用注入的方式得到了一個 IMemoryCache 對象,在 Get() 方法中增長了一條緩存記錄 "userId=0001",而後在 Get(int id) 接口中提取該緩存記錄
運行程序,分別調用 Get() 和 Get(int id) 接口,得到下面的輸出信息緩存
這看起來很是容易,幾乎不用什麼思考,你就學會了在 Asp.Net Core 中使用緩存,容易使用,這很是重要,這也是一門語言普遍推廣的根本態度服務器
IMemoryCache 還包含了一個帶參數的構造方法,讓咱們能夠對緩存進行靈活的配置,該配置由類 MemoryCacheOptions 決定異步
public class MemoryCacheOptions : IOptions<MemoryCacheOptions> { public MemoryCacheOptions(); public ISystemClock Clock { get; set; } [Obsolete("This is obsolete and will be removed in a future version.")] public bool CompactOnMemoryPressure { get; set; } public TimeSpan ExpirationScanFrequency { get; set; } public long? SizeLimit { get; set; } public double CompactionPercentage { get; set; } }
上面的這個配置很是簡單,在系統中應用相似下面的代碼這樣性能
public void ConfigureServices(IServiceCollection services) { services.AddMemoryCache(options => { options.CompactionPercentage = 0.02d; options.ExpirationScanFrequency = TimeSpan.FromMinutes(5); options.SizeLimit = 1024; }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }
上面的緩存策略設置爲緩存壓縮比爲 2%,每 5 分鐘進行一次過時緩存的掃描,最大緩存空間大小限制爲 1024
使用方法不變字體
因爲緩存的全部鍵其緩存過時優先級都是默認的 Normal,可能咱們須要在某些業務場景下,讓某些緩存值設置一個較高的優先級,好比設置永遠都不過時,這樣即便緩存達到最大限制條數之後也不會對其進行清理this
public enum CacheItemPriority { Low = 0, Normal = 1, High = 2, NeverRemove = 3 }
[HttpGet] public ActionResult<IEnumerable<string>> Get() { MemoryCacheEntryOptions entry = new MemoryCacheEntryOptions { Priority = CacheItemPriority.NeverRemove }; cache.Set("userId", "0001", entry); return new string[] { "value1", "value2" }; }
上面的代碼表示,咱們對緩存鍵 "userId" 應用了一個 「永不移除」 的策略,固然,還能夠對單個值作很是多的策略,好比如今 "userId" 的值大小等等,有興趣的同窗能夠深刻了解 MemoryCacheEntryOptions 類code
緩存依賴的意思是表示,一個或者多個緩存依賴於某個緩存,當某個緩存過時的時候,對其有依賴條件的其它緩存也會過時,在某些應用場景下,緩存依賴很是有用
如下示例使用一個模擬用戶登陸/登出的業務場景
[Route("api/[controller]")] [ApiController] public class TokenController : ControllerBase { private IMemoryCache cache; public TokenController(IMemoryCache cache) { this.cache = cache; } // 建立註冊依賴 [HttpGet("login")] public ActionResult<string> Login() { var cts = new CancellationTokenSource(); cache.Set(CacheKeys.DependentCTS, cts); using (var entry = cache.CreateEntry(CacheKeys.UserSession)) { entry.Value = "_x0123456789"; entry.RegisterPostEvictionCallback(DependentEvictionCallback, this); cache.Set(CacheKeys.UserShareData, "這裏是共享的數據", new CancellationChangeToken(cts.Token)); cache.Set(CacheKeys.UserCart, "這裏是購物車", new CancellationChangeToken(cts.Token)); } return "設置依賴完成"; } // 獲取緩存 [HttpPost("getkeys")] public IActionResult GetKeys() { var userInfo = new { UserSession = cache.Get<string>(CacheKeys.UserSession), UserShareData = cache.Get<string>(CacheKeys.UserShareData), UserCart = cache.Get<string>(CacheKeys.UserCart) }; return new JsonResult(userInfo); } // 移除緩存 [HttpPost("logout")] public ActionResult<string> LogOut() { cache.Get<CancellationTokenSource>(CacheKeys.DependentCTS).Cancel(); var userInfo = new { UserSession = cache.Get<string>(CacheKeys.UserSession), UserShareData = cache.Get<string>(CacheKeys.UserShareData), UserCart = cache.Get<string>(CacheKeys.UserCart) }; return new JsonResult(userInfo); } // 過時通知 private static void DependentEvictionCallback(object key, object value, EvictionReason reason, object state) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Key:{0} 已過時,依賴於該 Key 的全部緩存都將過時而處於不可用狀態", key); Console.ForegroundColor = ConsoleColor.Gray; } }
上面的代碼使用 CancellationTokenSource 用做事件通知源,當移除 CacheKeys.DependentCTS 並觸發 CancellationTokenSource.Cancel() 方法後,將異步觸發 DependentEvictionCallback(object key, object value, EvictionReason reason, object state)委託;此時,託管程序收到一個通知,用戶已登出,已移除用戶相關緩存,任何移除接口嘗試再次讀取 CacheKeys 項,此時,返回值爲空
能夠看到,在用戶登陸登出這個業務場景下,使用緩存依賴項對其相關緩存進行管理,仍是很是方便的,當用戶退出登陸後,即清空其全部相關緩存
https://github.com/lianggx/EasyAspNetCoreDemo/tree/master/Ron.MemoryCacheDemo