标签:lock await void memory 技术 需要 tag ict eof
MemoryCache是.Net Framework4.0中加入的内存缓存类;
在.Net Core的版本中,加入了以下内容:
1.缓存过期的回调
2.缓存容量的控制
3.缓存项优先级设定
4.缓存压缩
准备工作:Nuget安装Microsoft.Extensions.Caching.Memory
在被动过期中,对过期时间的控制主要提供了绝对时间的过期、滑动时间过期两种方式。
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.Set<string>("key", "test", cacheopetions); //每秒取一次 for (int i = 0; i < 100; i++) { await Task.Delay(1000); Console.WriteLine(i); cache.Get("key"); }
使用AbsoluteExpiration 设置绝对过期时间,上面设置为5秒过期;
使用MemoryCacheEntryOptions对象的RegisterPostEvictionCallback方法通过传递委托的方式注册回调函数
每秒运行一次,看下运行结果:
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.Set<string>("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.Set<string>(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.Set<string>(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, Func<CacheEntry, long> 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<CacheEntry> list = new List<CacheEntry>(); List<CacheEntry> list2 = new List<CacheEntry>(); List<CacheEntry> list3 = new List<CacheEntry>(); List<CacheEntry> list4 = new List<CacheEntry>(); 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