ASP.NET Core 中的缓存 / MemoryCache
十年河东,十年河西,莫欺少年穷
学无止境,精益求精
ASP.NET Core 缓存Caching,.NET Core 中为我们提供了Caching 的组件。
目前Caching 组件提供了三种存储方式。
Memory
Redis
SqlServer
学习在ASP.NET Core 中使用Caching。
Memory Caching
1.新建一个 ASP.NET Core 项目,选择Web 应用程序,将身份验证 改为 不进行身份验证。
2.添加引用
Install-Package Microsoft.Extensions.Caching.Memory
3.使用
在Startup.cs 中 ConfigureServices
public void ConfigureServices(IServiceCollection services) { services.AddMemoryCache(); // Add framework services. services.AddMvc(); }
然后在控制器中依赖注入、
private IMemoryCache _cache; public LongLongController(IMemoryCache memoryCache) { _cache = memoryCache; }
1、方法:TryGetValue 及 方法缓存的存取
public IActionResult Index() { string cacheKey_2 = "CacheKey"; List<string> cacheEntry; //如果缓存没有过期,则Out测试就是缓存存储的值,注意存放值的类型应该和Out参数一致。 var bol = _cache.TryGetValue<List<string>>(cacheKey_2, out cacheEntry); //判断缓存是否存在 if (!bol) { List<string> lst = new List<string>() { "陈大六", "陈卧龙", "陈新宇", "刘丽", "花国锋" }; var cacheEntryOptions = new MemoryCacheEntryOptions() .SetSlidingExpiration(TimeSpan.FromMinutes(10)); _cache.Set(cacheKey_2, lst, cacheEntryOptions); } ViewBag.cacheEntry = _cache.Get(cacheKey_2); return View(); }
在TryGetValue 中,Out 参数的类型应与缓存中存储的值的类型一致。否则TryGetValue 中的Out参数永远为NULL。
2、设置缓存的过期时间,可采用绝对过期时间或相对过期时间两种模式;
相对过期时间设置方式:
var cacheEntryOptions = new MemoryCacheEntryOptions() .SetSlidingExpiration(TimeSpan.FromSeconds(10));
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/// <summary> /// 相对过期时间十秒 如果:十秒内不间断有人访问,那么在访问期间缓存不会消失。除非前后访问时间大于十秒,缓存会消失 /// </summary> /// <returns></returns> public IActionResult Slid() { string cacheKey_2 = "SlidCache"; List<string> cacheEntry; var bol = _cache.TryGetValue<List<string>>(cacheKey_2, out cacheEntry); //判断缓存是否存在 if (!bol) { List<string> lst = new List<string>() { "陈大六", "陈卧龙", "陈新宇", "刘丽", "花国锋" }; var cacheEntryOptions = new MemoryCacheEntryOptions() .SetSlidingExpiration(TimeSpan.FromSeconds(10)); _cache.Set(cacheKey_2, lst, cacheEntryOptions); } ViewBag.cacheEntry = _cache.Get(cacheKey_2); return View(); }
注意上述代码中的备注;假设我们设置一个缓存的相对过期时间为10秒,缓存由A创建,十秒中内,B进入可系统,并读取了缓存,这时缓存的有效时间又会变成十秒,同理,只要缓存在十秒钟内不间断有其他人访问,则缓存永远不会过期。如果大于十秒,则缓存过期。
绝对过期时间设置方式:
var cacheEntryOptions = new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromSeconds(10));
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/// <summary> /// 绝对过期时间 10秒 /// </summary> /// <returns></returns> public IActionResult Abs() { string cacheKey_2 = "SlidCache"; List<string> cacheEntry; var bol = _cache.TryGetValue<List<string>>(cacheKey_2, out cacheEntry); //判断缓存是否存在 if (!bol) { List<string> lst = new List<string>() { "陈大六", "陈卧龙", "陈新宇", "刘丽", "花国锋" }; var cacheEntryOptions = new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromSeconds(10)); _cache.Set(cacheKey_2, lst, cacheEntryOptions); } ViewBag.cacheEntry = _cache.Get(cacheKey_2); return View(); }
绝对过期时间不管期间有没有人访问,在时间过后,就会过期,清空。
3、移除缓存
_cache.Remove(cacheKey_2);
移除缓存没什么好说的,就是把缓存清空
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/// <summary> /// 测试移除缓存 /// </summary> /// <returns></returns> public IActionResult Remove() { //先添加缓存 string cacheKey_2 = "RemoveCache"; List<string> lst = new List<string>() { "陈大六", "陈卧龙", "陈新宇", "刘丽", "花国锋" }; var cacheEntryOptions = new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromHours(10)); _cache.Set(cacheKey_2, lst, cacheEntryOptions); //直接移除 _cache.Remove(cacheKey_2); return View(); }
4、缓存的优先级分为四种:永不过期 大于 高优先级 大于 一般优先级 大于 低优先级。
/缓存优先级 (程序压力大时,会根据优先级自动回收)
永不过期:
var cacheEntryOptions = new MemoryCacheEntryOptions() .SetPriority(CacheItemPriority.NeverRemove);
高优先级:
var HighCacheEntryOptions = new MemoryCacheEntryOptions() .SetPriority(CacheItemPriority.High);
一般优先级:
var NormalCacheEntryOptions = new MemoryCacheEntryOptions() .SetPriority(CacheItemPriority.Normal);
低优先级:
var LowCacheEntryOptions = new MemoryCacheEntryOptions() .SetPriority(CacheItemPriority.Low);
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/// <summary> /// 缓存优先级 /// </summary> /// <returns></returns> public IActionResult CacheLevel() { List<string> lst = new List<string>() { "陈大六", "陈卧龙", "陈新宇", "刘丽", "花国锋" }; //NeverRemove 最高优先级 永远不会过期 string NeverRemove = "NeverRemove"; var cacheEntryOptions = new MemoryCacheEntryOptions() .SetPriority(CacheItemPriority.NeverRemove); _cache.Set(NeverRemove, lst, cacheEntryOptions); // //High 高优先级 永远不会过期 string High = "High"; var HighCacheEntryOptions = new MemoryCacheEntryOptions() .SetPriority(CacheItemPriority.High); _cache.Set(High, lst, cacheEntryOptions); //Normal 一般的优先级 永远不会过期 string Normal = "Normal"; var NormalCacheEntryOptions = new MemoryCacheEntryOptions() .SetPriority(CacheItemPriority.Normal); _cache.Set(Normal, lst, cacheEntryOptions); //Normal 一般的优先级 永远不会过期 string Low = "Low"; var LowCacheEntryOptions = new MemoryCacheEntryOptions() .SetPriority(CacheItemPriority.Low); _cache.Set(Low, lst, cacheEntryOptions); return View(); }
5、缓存过期后,执行回调函数,
_cache.Set(cacheKey, lst, new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromSeconds(10)) .RegisterPostEvictionCallback((key, value, reason, substate) => { //调用回调函数 GetIntList(key,value,reason,substate); }));
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public IActionResult cacheCallback() { List<string> lst = new List<string>() { "陈大六", "陈卧龙", "陈新宇", "刘丽", "花国锋" }; //缓存回调 10秒过期会回调 string cacheKey = "cacheKey"; _cache.Set(cacheKey, lst, new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromSeconds(10)) .RegisterPostEvictionCallback((key, value, reason, substate) => { //调用回调函数 GetIntList(key,value,reason,substate); })); // return View(); } public void GetIntList(object key,object value, object reason, object substate) { List<string> lst=(List<string>)value; //说白了就是被释放了 Console.WriteLine($"键{key}的缓存因:{reason}而改变。"); foreach(var item in lst) { Console.WriteLine(item); } }
6、缓存回调 根据Token过期
var cts = new CancellationTokenSource(); _cache.Set(cacheKey, lst, new MemoryCacheEntryOptions() .AddExpirationToken(new CancellationChangeToken(cts.Token)) .RegisterPostEvictionCallback((key, value, reason, substate) => { Console.WriteLine($"键{key}值{value}改变,因为{reason}"); })); cts.Cancel(); //执行到Cancel()方法时,会执行回调删除
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public ActionResult CacheToken() { List<string> lst = new List<string>() { "陈大六", "陈卧龙", "陈新宇", "刘丽", "花国锋" }; string cacheKey = "CacheToken"; //缓存回调 根据Token过期 var cts = new CancellationTokenSource(); _cache.Set(cacheKey, lst, new MemoryCacheEntryOptions() .AddExpirationToken(new CancellationChangeToken(cts.Token)) .RegisterPostEvictionCallback((key, value, reason, substate) => { Console.WriteLine($"键{key}值{value}改变,因为{reason}"); })); cts.Cancel(); //执行到Cancel()方法时,会执行回调删除 return View(); }
7、页面缓存、distributed-cache
Cshtml页面代码如下:
<distributed-cache name="mycache" expires-after="TimeSpan.FromSeconds(10)"> <p>缓存项10秒过期-LineZero</p> @DateTime.Now </distributed-cache> <distributed-cache name="mycachenew" expires-sliding="TimeSpan.FromSeconds(10)"> <p>缓存项有人访问就不会过期,无人访问10秒过期-LineZero</p> @DateTime.Now </distributed-cache>
这样就能缓存标签内的内容。
如果你觉得本文对你有帮助,请点击“推荐”,谢谢。
@陈卧龙的博客