詳解.Net緩存之MemoryCahe
1. MemoryCahe
NetCore中的緩存和System.Runtime.Caching很相似,但是在功能上做了增強,緩存的key支持object類型;提供了泛型支持;可以讀緩存和單個緩存項的大小做限定,可以設(shè)置緩存的壓縮比例。
通過實現(xiàn)微軟官方的Microsoft.Extensions.Caching里面的IDistributedCache接口實現(xiàn)緩存集成到ASPNETCore中
1.1 簡單入門
netcore中緩存相關(guān)的類庫都在 Microsoft.Extensions.Caching ,使用MemoryCache首先安裝包
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0" />
注入
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); //添加緩存配置 services.AddMemoryCache(); }
使用
private readonly IMemoryCache _cache; public HomeController(IMemoryCache cache) { _cache = cache; } [HttpGet] public string Set() { //寫 _cache.Set("login", "4545478244"); return ""; } [HttpGet] public string Get() { //讀 var value = _cache.Get("login"); return ""; }
1.2 過期時間
//1.最簡單使用方式 _cache.Set("mykey", "myvalue"); //2.絕對過期時間,3秒后過期 _cache.Set("key1", "value1", new DateTimeOffset(DateTime.Now.AddSeconds(3))); //3.絕對過期時間,效果同上 _cache.Set("key2", "value2", TimeSpan.FromSeconds(3)); //4.滑動過期時間,3秒后,即三秒鐘內(nèi)被訪問,則重新刷新緩存時間為3秒后 _cache.Set("key3", "value3", new MemoryCacheEntryOptions { SlidingExpiration = TimeSpan.FromSeconds(3), }); Console.WriteLine("-----------暫停2秒"); Thread.Sleep(2000);//暫停2秒 Console.WriteLine($"key1的值:{_cache.Get("key1") ?? "key1被清除"}"); Console.WriteLine($"key2的值:{_cache.Get("key2") ?? "key2被清除"}"); Console.WriteLine($"key3的值:{_cache.Get("key3") ?? "key3被清除"}"); Console.WriteLine("-----------暫停2秒"); Thread.Sleep(2000);//再次暫停2秒 Console.WriteLine($"key1的值:{_cache.Get("key1") ?? "key1被清除"}"); Console.WriteLine($"key2的值:{_cache.Get("key2") ?? "key2被清除"}"); Console.WriteLine($"key3的值:{_cache.Get("key3") ?? "key3被清除"}");
在例子中key1,key2都是使用的絕對過期時間,key3使用的相對過期時間,2秒后第一次訪問key1、key2、key3都沒過期,其中key3的過期時間刷新了,重新設(shè)置為3秒后,所以再次暫停2秒后,key1、key2都過期了,key3仍然存在。
程序運行結(jié)果如下:
1.2 常用配置
下邊的例子介紹netcore中緩存的常用配置,直接看代碼
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddMemoryCache(options => { //緩存大小 options.SizeLimit = 3;//如果設(shè)置了該值,那么每個set都必須設(shè)置size,并且超過了這個值的大小的會自動銷毀 //緩存滿了時,壓縮20%(即刪除20份優(yōu)先級低的緩存項) options.CompactionPercentage = 0.2; //兩秒鐘查找一次過期項 options.ExpirationScanFrequency = TimeSpan.FromSeconds(3); }); } [HttpGet] public string TestSize() { //SizeLimit配置3 _cache.Set("item1", "11111", new MemoryCacheEntryOptions { //緩存大小占1份 Size = 2 }); _cache.Set("item2", "22222", new MemoryCacheEntryOptions { Size = 2 }); var item1 = _cache.Get("item1");//輸出 11111 var item2 = _cache.Get("item2");//輸出 null return ""; } [HttpGet] public string TestOptions() { //單個緩存項的配置 MemoryCacheEntryOptions cacheEntityOps = new MemoryCacheEntryOptions() { //絕對過期時間1 //AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddSeconds(2)), //絕對過期時間2 //AbsoluteExpirationRelativeToNow=TimeSpan.FromSeconds(3), //相對過期時間 SlidingExpiration = TimeSpan.FromSeconds(3), //優(yōu)先級,當(dāng)緩存壓縮時會優(yōu)先清除優(yōu)先級低的緩存項 Priority = CacheItemPriority.Low,//優(yōu)先級等級:Low,Normal,High,NeverRemove //緩存大小占1份 Size = 1 }; //注冊緩存項被清除時的回調(diào),可以注冊多個回調(diào) cacheEntityOps.RegisterPostEvictionCallback((key, value, reason, state) => { Console.WriteLine($"回調(diào)函數(shù)輸出【鍵:{key},值:{value},被清除的原因:{reason}】"); }); _cache.Set("mykey", "myvalue", cacheEntityOps); Console.WriteLine($"mykey的值:{_cache.Get("mykey") ?? "mykey緩存被清除了"}"); Console.WriteLine("------------------暫停3秒"); Thread.Sleep(3000); Console.WriteLine($"mykey的值:{_cache.Get("mykey") ?? "mykey緩存被清除了"}"); return ""; }
注意netcore中設(shè)置緩存和緩存項大小是沒有單位的
緩存被清空的回調(diào)函數(shù)可以注冊多個(System.Runtime.Caching清除緩存的回調(diào)只能是一個)。
程序執(zhí)行結(jié)果
1.3 IChangeToken
上邊我們已經(jīng)簡單了解了通過滑動過期時間和絕對過期時間來控制緩存的有效性,但是有時緩存的過期與否和時間沒有聯(lián)系,比如我們緩存一個文件的內(nèi)容,不管緩存多久只要文件沒有發(fā)生變化緩存都是有效的。在net framework中我們可以通過CacheDependency來控制,在net core中怎么控制呢?net core中我們可以使用IChangeToken接口輕松實現(xiàn)緩存的過期策略。先看一下IChangeToken接口:
public interface IChangeToken { // 是否有變化發(fā)生 bool HasChanged { get; } // token是否會調(diào)用回調(diào)函數(shù),為true時才會有效 bool ActiveChangeCallbacks { get; } // 注冊一個回調(diào)函數(shù),當(dāng)有變化時觸發(fā)回調(diào) IDisposable RegisterChangeCallback(Action<object> callback, object state); }
看一下IChangeToken實現(xiàn)緩存過期策略的兩個例子
1.3.1 監(jiān)控文件
需要安裝組件:Microsoft.Extensions.FileProviders.Physical
internal class Program { private static void Main(string[] args) { string fileName = Path.Combine(Environment.CurrentDirectory, "someCacheData.xml"); var fileInfo = new FileInfo(fileName); MemoryCache myCache = new MemoryCache(new MemoryCacheOptions() { }); MemoryCacheEntryOptions cacheEntityOps = new MemoryCacheEntryOptions(); //PollingFileChangeToken是IChangeToken的實現(xiàn)類,通過輪詢監(jiān)控文件變化 cacheEntityOps.AddExpirationToken(new Microsoft.Extensions.FileProviders.Physical.PollingFileChangeToken(fileInfo)); //緩存失效時,回調(diào)函數(shù) cacheEntityOps.RegisterPostEvictionCallback((key, value, reason, state) => { Console.WriteLine($"文件【{key}】改動了"); }); //添加緩存,key為文件名,value為文件內(nèi)容 myCache.Set(fileInfo.Name, File.ReadAllText(fileName), cacheEntityOps); Console.WriteLine(myCache.Get(fileInfo.Name)); } }
PollingFileChangeToken通過輪詢來監(jiān)控文件有沒有發(fā)生變化,如果文件中的內(nèi)容發(fā)生改變,緩存就會自動過期。
1.3.2 通過代碼控制緩存過期
class Program { static void Main(string[] args) { MemoryCache memoryCache = new MemoryCache(new MemoryCacheOptions()); MemoryCacheEntryOptions cacheEntityOps = new MemoryCacheEntryOptions(); //使用CancellationChangeToken控制緩存過期 CancellationTokenSource tokenSource = new CancellationTokenSource(); cacheEntityOps.AddExpirationToken(new CancellationChangeToken(tokenSource.Token)); //設(shè)置緩存 memoryCache.Set("mykey", "myvalue", cacheEntityOps); Console.WriteLine(memoryCache.Get("mykey") ?? "緩存被清除了"); //通過代碼清除緩存 tokenSource.Cancel(); Console.WriteLine(memoryCache.Get("mykey") ?? "緩存被清除了"); } }
tokenSource.Cancel方法發(fā)送取消信號,這個方法會觸發(fā)緩存過期,基于此我們可以通過Cancel方法靈活的實現(xiàn)自定義的緩存策略。
程序執(zhí)行結(jié)果如下:
1.4 引用Nuget包
直接引用我自己簡單封裝的一個Nuget包(簡單封裝自己用,不要嘲笑)
<PackageReference Include="Common.Cache.MemoryCache" Version="1.1.0" />
注入到容器
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); //注入 services.AddMemoryCacheExtension(); }
使用
# 在需要使用的地方進行注入 private readonly IMemoryCachimg _cache; public HomeController(IMemoryCachimg cache) { _cache = cache; }
以上就是詳解.Net緩存之MemoryCahe的詳細(xì)內(nèi)容,更多關(guān)于.Net緩存之MemoryCahe的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
.NET?6開發(fā)TodoList應(yīng)用之請求日志組件HttpLogging介紹
這篇文章介紹了.NET?6開發(fā)TodoList應(yīng)用之請求日志組件HttpLogging,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-01-01CKEditor與dotnetcore實現(xiàn)圖片上傳功能
這篇文章主要為大家詳細(xì)介紹了CKEditor與dotnetcore實現(xiàn)圖片上傳功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09asp.net讀取excel中的數(shù)據(jù)并綁定在gridview
這篇文章主要介紹了asp.net讀取excel中的數(shù)據(jù)并綁定在gridview上的方法,需要的朋友可以參考下2014-02-02Asp.net treeview實現(xiàn)無限級樹實現(xiàn)代碼
最近研究了一下treeview,發(fā)現(xiàn)有兩種實現(xiàn)無限級樹的方法,文字不想多寫,直入主題。2009-09-09asp.net下獲取遠(yuǎn)程網(wǎng)頁的內(nèi)容之二(downmoon原創(chuàng))
asp.net下獲取遠(yuǎn)程網(wǎng)頁的內(nèi)容之二(downmoon原創(chuàng))...2007-04-04ASP.Net?Core讀取配置文件的三種方法小結(jié)
ASP.NET?Core支持多種格式的配置文件,如JSON、XML、INI等,本文就來介紹一下ASP.Net?Core讀取配置文件的三種方法,感興趣的可以了解一下2024-02-02