• .net core系列之《在.net core中使用MemoryCache实现本地缓存》


    说到内存缓存MemoryCache不由的让我想起.Net Framework中的MemoryCache,它位于 System.Runtime.Caching 程序集中。

    接下来我们来看看.net core中的MemoryCache又有什么与众不同的地方吧。

    一、基本实现

      1、打开NuGet包管理器搜索并安装 Microsoft.Extensions.Caching.Memory 包,或者从程序包管理控制台执行 Install-Package Microsoft.Extensions.Caching.Memory 命令

      2、接下来看实现代码

            static void Main(string[] args)
            {
                MemoryCache memoryCache = new MemoryCache(new MemoryCacheOptions());
                memoryCache.Set("name","tom");
                var value = memoryCache.Get("name");
                Console.WriteLine(value);
    
                Console.ReadKey();
            }

      结果如下:

      

    二、缓存容量控制:SizeLimit

      1、当你用SizeLimit属性设置了这个缓存大小之后,你就必须为你缓存中的每一项设置大小,否则则报错。当然,当你的大小达到你设置的SizeLimit时,你再设置缓存,它会自动清理一些缓存再缓存你设置的值

      2、代码如下:

            static void Main(string[] args)
            {
                MemoryCache memoryCache = new MemoryCache(new MemoryCacheOptions()
                {
                    SizeLimit = 100
                });
                for (int i = 0; i < 1000; i++)
                {
                    memoryCache.Set<int>(i.ToString(), i, new MemoryCacheEntryOptions() {
                        Size = 1
                    });
                }
                Console.WriteLine(memoryCache.Count);
    
                Console.ReadKey();
            }

      结果如下:

      

      实际结果不是1000,而是100

      我们来看看它设置值的过程是什么样的:

      

      由于设置的大小为100,达到100时再设置缓存项就会自动清理掉一部分

    三、缓期的过期问题

    1、被动过期

      代码如下:

            static void Main(string[] args)
            {
                MemoryCache memoryCache = new MemoryCache(new MemoryCacheOptions());
                memoryCache.Set("name", "jack", new MemoryCacheEntryOptions()
                {
                    AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(5)//设置为5秒后过期
                });
                while (true)
                {
                    System.Threading.Thread.Sleep(1000);
                    string value;
                    if (!memoryCache.TryGetValue("name", out value))
                    {
                        value = "已过期";
                    }
                    Console.WriteLine(value);
                }
                //Console.ReadKey();
            }

      结果如下:

      

    2、主动过期

            static void Main(string[] args)
            {
                MemoryCache memoryCache = new MemoryCache(new MemoryCacheOptions());
    
                CancellationTokenSource tokenSource = new CancellationTokenSource();
                var cacheOptins = new MemoryCacheEntryOptions()
                {
                    AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(10)//设置为10秒后过期
                };
                cacheOptins.AddExpirationToken(new CancellationChangeToken(tokenSource.Token));
    
                memoryCache.Set("name", "jack", cacheOptins);
    
                tokenSource.CancelAfter(2000);//主动设置为2秒过期
                while (true)
                {
                    Thread.Sleep(1000);
                    string value;
                    if (!memoryCache.TryGetValue("name", out value))
                    {
                        value = "已过期";
                    }
                    Console.WriteLine(value);
                }
                //Console.ReadKey();
            }

      结果如下:

      

    3、过期后回调:  

      static void Main(string[] args)
            {
                MemoryCache memoryCache = new MemoryCache(new MemoryCacheOptions());
    
                CancellationTokenSource tokenSource = new CancellationTokenSource();
                var cacheOptins = new MemoryCacheEntryOptions()
                {
                    AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(10)//设置为10秒后过期
                };
                cacheOptins.AddExpirationToken(new CancellationChangeToken(tokenSource.Token));
    
                cacheOptins.RegisterPostEvictionCallback((key, value, reason, state) => {
                    Console.WriteLine(reason);
                });
    
                memoryCache.Set("name", "jack", cacheOptins);
    
                tokenSource.CancelAfter(2000);//主动设置为2秒过期
                while (true)
                {
                    Thread.Sleep(1000);
                    string value;
                    if (!memoryCache.TryGetValue("name", out value))
                    {
                        value = "已过期";
                    }
                    Console.WriteLine(value);
                }
                //Console.ReadKey();
            }

      结果如下:

      

    四、其它的一些设置

    1、原子性操作

     memoryCache.GetOrCreate("name", entry => "lucy");

    2、优先级设置,这个设置是为了配合压缩缓存的

    以下是系统定义的优先级的枚举

        public enum CacheItemPriority
        {
            Low = 0,
            Normal = 1,
            High = 2,
            NeverRemove = 3
        }

    接下来设定优先级

     var cacheOptins = new MemoryCacheEntryOptions()
                {
                    Priority= CacheItemPriority.Low,
                    AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(10)//设置为10秒后过期
                };

    3、缓存压缩

            static void Main(string[] args)
            {
                MemoryCache memoryCache = new MemoryCache(new MemoryCacheOptions()
                {
                    SizeLimit = 100
                });
                for (int i = 0; i < 100; i++)
                {
                    CacheItemPriority priority = CacheItemPriority.Low;
                    if (25 < i && i < 50)
                        priority = CacheItemPriority.Normal;
                    else if (50 < i && i < 75)
                        priority = CacheItemPriority.High;
                    else
                        priority = CacheItemPriority.NeverRemove;
                    memoryCache.Set(i.ToString(), i.ToString(), new MemoryCacheEntryOptions()
                    {
                        Size = 1,
                        Priority = priority,
                        AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(10)//设置为10秒后过期
                    });
                }
                memoryCache.Compact(0.2);//压缩20%
                Console.WriteLine(memoryCache.Count);
                for (int i = 0; i < 100; i++)
                {
                    Console.WriteLine(memoryCache.Get(i.ToString()));
                }
                Console.ReadKey();
            }

    结果如下:

    压缩后的缓存项数:

    被压缩的缓存项:

    根据结果可知道,优先级为 CacheItemPriority.Normal 的数据被压缩掉了,由此可见,优先级为 CacheItemPriority.Low 的并没有参加压缩。

    压缩的优先级顺序是 CacheItemPriority.Normal>CacheItemPriority.High>CacheItemPriority.NeverRemove 

  • 相关阅读:
    作业day04
    python开发学习day03 (基本数据类型; 输入输出; 基本运算符)
    作业day03
    作业day02
    python开发学习day02 (编程语言; 解释器 ; 运行方式; IDE; 变量)
    BasePage基础页面的封装
    设定浏览器驱动
    webdriver(chrome无头浏览器)
    webdriervAPI(窗口截图)
    webdriervAPI(常用的js方法)
  • 原文地址:https://www.cnblogs.com/hhzblogs/p/9720248.html
Copyright © 2020-2023  润新知