詳解.Net緩存之MemoryCahe

詳解.net緩存之memorycahe

 

1. memorycahe

netcore中的緩存和system.runtime.caching很相似,但是在功能上做了增強(qiáng),緩存的key支持object類型;提供了泛型支持;可以讀緩存和單個(gè)緩存項(xiàng)的大小做限定,可以設(shè)置緩存的壓縮比例。

通過(guò)實(shí)現(xiàn)微軟官方的microsoft.extensions.caching里面的idistributedcache接口實(shí)現(xiàn)緩存集成到aspnetcore中

1.1 簡(jiǎn)單入門

netcore中緩存相關(guān)的類庫(kù)都在 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 過(guò)期時(shí)間

          //1.最簡(jiǎn)單使用方式
          _cache.set("mykey", "myvalue");
          //2.絕對(duì)過(guò)期時(shí)間,3秒后過(guò)期
          _cache.set("key1", "value1", new datetimeoffset(datetime.now.addseconds(3)));
          //3.絕對(duì)過(guò)期時(shí)間,效果同上
          _cache.set("key2", "value2", timespan.fromseconds(3));
          //4.滑動(dòng)過(guò)期時(shí)間,3秒后,即三秒鐘內(nèi)被訪問(wèn),則重新刷新緩存時(shí)間為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都是使用的絕對(duì)過(guò)期時(shí)間,key3使用的相對(duì)過(guò)期時(shí)間,2秒后第一次訪問(wèn)key1、key2、key3都沒(méi)過(guò)期,其中key3的過(guò)期時(shí)間刷新了,重新設(shè)置為3秒后,所以再次暫停2秒后,key1、key2都過(guò)期了,key3仍然存在。

程序運(yùn)行結(jié)果如下:

1.2 常用配置

下邊的例子介紹netcore中緩存的常用配置,直接看代碼

      public void configureservices(iservicecollection services)
      {
          services.addcontrollers();

          services.addmemorycache(options =>
          {
              //緩存大小
              options.sizelimit = 3;//如果設(shè)置了該值,那么每個(gè)set都必須設(shè)置size,并且超過(guò)了這個(gè)值的大小的會(huì)自動(dòng)銷毀 
              //緩存滿了時(shí),壓縮20%(即刪除20份優(yōu)先級(jí)低的緩存項(xiàng))
              options.compactionpercentage = 0.2;
              //兩秒鐘查找一次過(guò)期項(xiàng)
              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()
      {
          //單個(gè)緩存項(xiàng)的配置
          memorycacheentryoptions cacheentityops = new memorycacheentryoptions()
          {
              //絕對(duì)過(guò)期時(shí)間1
              //absoluteexpiration = new datetimeoffset(datetime.now.addseconds(2)),
              //絕對(duì)過(guò)期時(shí)間2
              //absoluteexpirationrelativetonow=timespan.fromseconds(3),
              //相對(duì)過(guò)期時(shí)間
              slidingexpiration = timespan.fromseconds(3),
              //優(yōu)先級(jí),當(dāng)緩存壓縮時(shí)會(huì)優(yōu)先清除優(yōu)先級(jí)低的緩存項(xiàng)
              priority = cacheitempriority.low,//優(yōu)先級(jí)等級(jí):low,normal,high,neverremove
              //緩存大小占1份
              size = 1
          };
          //注冊(cè)緩存項(xiàng)被清除時(shí)的回調(diào),可以注冊(cè)多個(gè)回調(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è)置緩存和緩存項(xiàng)大小是沒(méi)有單位的

緩存被清空的回調(diào)函數(shù)可以注冊(cè)多個(gè)(system.runtime.caching清除緩存的回調(diào)只能是一個(gè))。

程序執(zhí)行結(jié)果

1.3 ichangetoken

上邊我們已經(jīng)簡(jiǎn)單了解了通過(guò)滑動(dòng)過(guò)期時(shí)間和絕對(duì)過(guò)期時(shí)間來(lái)控制緩存的有效性,但是有時(shí)緩存的過(guò)期與否和時(shí)間沒(méi)有聯(lián)系,比如我們緩存一個(gè)文件的內(nèi)容,不管緩存多久只要文件沒(méi)有發(fā)生變化緩存都是有效的。在net framework中我們可以通過(guò)cachedependency來(lái)控制,在net core中怎么控制呢?net core中我們可以使用ichangetoken接口輕松實(shí)現(xiàn)緩存的過(guò)期策略。先看一下ichangetoken接口:

  public interface ichangetoken
  {
      // 是否有變化發(fā)生
      bool haschanged { get; }
      // token是否會(huì)調(diào)用回調(diào)函數(shù),為true時(shí)才會(huì)有效 
      bool activechangecallbacks { get; }
      // 注冊(cè)一個(gè)回調(diào)函數(shù),當(dāng)有變化時(shí)觸發(fā)回調(diào)
      idisposable registerchangecallback(action<object> callback, object state);
  }

看一下ichangetoken實(shí)現(xiàn)緩存過(guò)期策略的兩個(gè)例子

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的實(shí)現(xiàn)類,通過(guò)輪詢監(jiān)控文件變化
          cacheentityops.addexpirationtoken(new microsoft.extensions.fileproviders.physical.pollingfilechangetoken(fileinfo));
          //緩存失效時(shí),回調(diào)函數(shù)
          cacheentityops.registerpostevictioncallback((key, value, reason, state) => { console.writeline($"文件【{key}】改動(dòng)了"); });
          //添加緩存,key為文件名,value為文件內(nèi)容
          mycache.set(fileinfo.name, file.readalltext(filename), cacheentityops);
          console.writeline(mycache.get(fileinfo.name));
      }
  }

pollingfilechangetoken通過(guò)輪詢來(lái)監(jiān)控文件有沒(méi)有發(fā)生變化,如果文件中的內(nèi)容發(fā)生改變,緩存就會(huì)自動(dòng)過(guò)期。

1.3.2 通過(guò)代碼控制緩存過(guò)期

  class program
  {
      static void main(string[] args)
      {
          memorycache memorycache = new memorycache(new memorycacheoptions());
          memorycacheentryoptions cacheentityops = new memorycacheentryoptions();
          //使用cancellationchangetoken控制緩存過(guò)期
          cancellationtokensource tokensource = new cancellationtokensource();
          cacheentityops.addexpirationtoken(new cancellationchangetoken(tokensource.token));
          //設(shè)置緩存
          memorycache.set("mykey", "myvalue", cacheentityops);
          console.writeline(memorycache.get("mykey") ?? "緩存被清除了");
          //通過(guò)代碼清除緩存
          tokensource.cancel();
          console.writeline(memorycache.get("mykey") ?? "緩存被清除了");
      }
  }

tokensource.cancel方法發(fā)送取消信號(hào),這個(gè)方法會(huì)觸發(fā)緩存過(guò)期,基于此我們可以通過(guò)cancel方法靈活的實(shí)現(xiàn)自定義的緩存策略。

程序執(zhí)行結(jié)果如下:

1.4 引用nuget包

直接引用我自己簡(jiǎn)單封裝的一個(gè)nuget包(簡(jiǎn)單封裝自己用,不要嘲笑)

  <packagereference include="common.cache.memorycache" version="1.1.0" />

注入到容器

      public void configureservices(iservicecollection services)
      {
          services.addcontrollers();
          //注入
          services.addmemorycacheextension();
      }

使用

      # 在需要使用的地方進(jìn)行注入
      private readonly imemorycachimg  _cache;
      public homecontroller(imemorycachimg cache)
      {
          _cache = cache;
      }

以上就是詳解.net緩存之memorycahe的詳細(xì)內(nèi)容,更多關(guān)于.net緩存之memorycahe的資料請(qǐng)關(guān)注碩編程其它相關(guān)文章!

下一節(jié):如何在.net core中為grpc服務(wù)設(shè)計(jì)消息文件(proto)

asp.net編程技術(shù)

相關(guān)文章
亚洲国产精品第一区二区,久久免费视频77,99V久久综合狠狠综合久久,国产免费久久九九免费视频