.NET Core中内存缓存框架MemoryCache的基本使用

2021-02-10 08:16

阅读:676

标签:lock   await   void   memory   技术   需要   tag   ict   eof   

MemoryCache是.Net Framework4.0中加入的内存缓存类;

在.Net Core的版本中,加入了以下内容:

1.缓存过期的回调

2.缓存容量的控制

3.缓存项优先级设定

4.缓存压缩

准备工作:Nuget安装Microsoft.Extensions.Caching.Memory

一、被动过期、主动过期以及过期回调通知

在被动过期中,对过期时间的控制主要提供了绝对时间的过期、滑动时间过期两种方式。

1.绝对时间过期

            MemoryCache cache = new MemoryCache(new MemoryCacheOptions());
            //被动过期 (绝对时间过期)
            var cacheopetions = new MemoryCacheEntryOptions()
            {
                //设置过期时间(5秒)
                AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(5)
            };
            //设置过期回调函数
            cacheopetions.RegisterPostEvictionCallback((key, value, reason, obj) =>
            {
                Console.WriteLine(reason);
            });
            cache.Setstring>("key", "test", cacheopetions);
            //每秒取一次
            for (int i = 0; i 100; i++)
            {
                await Task.Delay(1000);
                Console.WriteLine(i);
                cache.Get("key");
            }

使用AbsoluteExpiration 设置绝对过期时间,上面设置为5秒过期;

使用MemoryCacheEntryOptions对象的RegisterPostEvictionCallback方法通过传递委托的方式注册回调函数

每秒运行一次,看下运行结果: 

技术图片

 

 2.滑动时间过期

            MemoryCache cache = new MemoryCache(new MemoryCacheOptions());
            //被动过期 (绝对时间过期)
            var cacheopetions = new MemoryCacheEntryOptions()
            {
                //设置过期时间(5秒)
                SlidingExpiration = TimeSpan.FromSeconds(5)
            };
            //设置过期回调函数
            cacheopetions.RegisterPostEvictionCallback((key, value, reason, obj) =>
            {
                Console.WriteLine(reason);
            });
            cache.Setstring>("key", "test", cacheopetions);

            for (int i = 0; i 100; i++)
            {
                Console.WriteLine(i);
                cache.Get("key");
                await Task.Delay(i*1000);
            }

跟绝对过期的程序差不多,AbsoluteExpiration 改为SlidingExpiration,并且使用TimeSpan。每次读取后都延长一秒等待时间,看下结果:

 技术图片

 

 无法满足5秒内命中就会过期

 二、缓存容量的控制

通过设置SizeLimit来控制缓存容量,看一下例程,设置最大为100,然后循环200次,加入200个值,看下值的数量

       MemoryCache cache = new MemoryCache(new MemoryCacheOptions()
            {
                SizeLimit = 100
            });
            for (int i = 0; i 200; i++)
            {
                cache.Setstring>(i.ToString(), i.ToString(), new MemoryCacheEntryOptions()
                {
                    Size = 1
                });
               Console.WriteLine(cache.Count);
            }

 技术图片

 

可以看到cache.Count一直不会超过100,一直在被丢弃。

 三、缓存压缩

使用Compact方法进行压缩,传入的参数是需要删减掉的百分比,例如下面例程是0.2,size是100,那就是删掉20%。

        MemoryCache cache = new MemoryCache(new MemoryCacheOptions()
            {
                SizeLimit = 100
            }) ;
            //压缩:
            for (int i = 0; i 100; i++)
            {
                cache.Setstring>(i, i.ToString(), new MemoryCacheEntryOptions()
                {
                    Size = 1
                });
            }
            cache.Compact(0.2); //表示移除的百分比

 

技术图片

 

压缩后剩下的数量为80个。

可以看一下压缩方法的源代码:

 

        public void Compact(double percentage)
        {
            int num = (int)((double)_entries.Count * percentage);
            Compact(num, (CacheEntry _) => 1L);
        }

        private void Compact(long removalSizeTarget, Funclong> computeEntrySize)
        {
            //IL_0072: Unknown result type (might be due to invalid IL or missing references)
            //IL_0077: Unknown result type (might be due to invalid IL or missing references)
            //IL_0079: Unknown result type (might be due to invalid IL or missing references)
            //IL_0090: Expected I4, but got Unknown
            //IL_00b7: Unknown result type (might be due to invalid IL or missing references)
            //IL_00bc: Unknown result type (might be due to invalid IL or missing references)
            List list = new List();
            List list2 = new List();
            List list3 = new List();
            List list4 = new List();
            long removedSize = 0L;
            DateTimeOffset utcNow = _options.Clock.get_UtcNow();
            foreach (CacheEntry value in _entries.Values)
            {
                if (value.CheckExpired(utcNow))
                {
                    list.Add(value);
                    removedSize += computeEntrySize(value);
                }
                else
                {
                    CacheItemPriority priority = value.Priority;
                    switch ((int)priority)
                    {
                        case 0:
                            list2.Add(value);
                            break;
                        case 1:
                            list3.Add(value);
                            break;
                        case 2:
                            list4.Add(value);
                            break;
                        default:
                            {
                                CacheItemPriority priority2 = value.Priority;
                                throw new NotSupportedException("Not implemented: " + ((object)priority2).ToString());
                            }
                        case 3:
                            break;
                    }
                }
            }
            ExpirePriorityBucket(ref removedSize, removalSizeTarget, computeEntrySize, list, list2);
            ExpirePriorityBucket(ref removedSize, removalSizeTarget, computeEntrySize, list, list3);
            ExpirePriorityBucket(ref removedSize, removalSizeTarget, computeEntrySize, list, list4);
            foreach (CacheEntry item in list)
            {
                RemoveEntry(item);
            }
        }

 

以上是MSCache的基本用法。

 

 

 

.NET Core中内存缓存框架MemoryCache的基本使用

标签:lock   await   void   memory   技术   需要   tag   ict   eof   

原文地址:https://www.cnblogs.com/cpy-648412294/p/13034820.html

上一篇:knockout.js

下一篇:jQuery


评论


亲,登录后才可以留言!