ASP.NET Core 中的内存缓存
MSDN:https://docs.microsoft.com/zh-cn/aspnet/core/performance/caching/memory?view=aspnetcore-5.0
1 引用Caching.Memory
1.1 NuGet安装Microsoft.Extensions.Caching.Memory
https://www.nuget.org/packages/Microsoft.Extensions.Caching.Memory/5.0.0?_src=template
1.2 Startup.cs的ConfigureServices中添加服务
1.3 代码中引用
using Microsoft.Extensions.Caching.Memory;
1.4 构造时注入
2 缓存的存取
2.1 Get和Set
Get获取缓存,如果没有命中,则用Set设置缓存
//使用缓存
public ActionResult CacatDate()
{
//基本用法:Get;Set
//读取缓存
string now = cache.Get<string>("cacheNow");
//如果缓存为null,则设置缓存
if (now == null)
{
now = DateTime.Now.ToString();
cache.Set("cacheNow", now);
}
return JsonResult(now);
}
2.2 GetOrCreate
如果命中缓存则获取,否则设置缓存
和使用GetSet效果一样
//使用缓存
public ActionResult CacatDate()
{
string now = cache.GetOrCreate("cacheNow", entry =>
{
return DateTime.Now.ToString();
});
return JsonResult(now);
}
2.3 设置过期时间
缓存过期的策略有两种。绝对过期时间和滑动过期时间。
绝对过期时间指:到指定的时间(比如2021年6月1日,或者当前系统日期+1天)后,缓存自动过期。
滑动过期时间指:设定一个滑动时间(比如10S)。如果缓存一直没有被命中过,则经过这个时间后过期。如果被命中,则重新计时这个时间。
注:如果同时设置两个策略,则满足任意一个策略的过期条件就会过期。
//使用缓存
public ActionResult CacatDate()
{
string now = cache.GetOrCreate("cacheNow", entry =>
{
entry.SetAbsoluteExpiration(TimeSpan.FromSeconds(10));//绝对过期时间
entry.SetSlidingExpiration(TimeSpan.FromSeconds(5));//滑动过期时间(规定时间内命中的话,重新计算时间)
return DateTime.Now.ToString();
});
return JsonResult(now);
}
2.4 缓存被删除时的回调函数
注册一个缓存被删除时的回调函数:entry.RegisterPostEvictionCallback
//使用缓存
public ActionResult CacatDate()
{
string now = cache.GetOrCreate("cacheNow", entry =>
{
entry.SetAbsoluteExpiration(TimeSpan.FromSeconds(10));//绝对过期时间
//entry.SetSlidingExpiration(TimeSpan.FromSeconds(5));//滑动过期时间(规定时间内命中的话,重新计算时间)
entry.RegisterPostEvictionCallback((key, value, reason, state) =>
{
Console.WriteLine("缓存删除,回调函数");
});
return DateTime.Now.ToString();
});
return JsonResult(now);
}
2.5 缓存域
缓存域是Caching.Memory自带的功能,得以实现缓存依赖。
什么是缓存依赖
通过检测依赖项缓存是否过期,判断缓存自身是否过期的一种方式。
测试缓存依赖
目前有两个模型。加油站和汽油。加油站依赖于汽油。
/// <summary>
/// 加油站
/// </summary>
public class OilStationModel
{
/// <summary>
/// 加油站名称
/// </summary>
public string OilStationName { get; set; }
/// <summary>
/// 加油站包含的汽油
/// </summary>
public OilModel Oil { get; set; }
}
/// <summary>
/// 汽油
/// </summary>
public class OilModel
{
/// <summary>
/// 汽油名称
/// </summary>
public string OilName { get; set; }
}
还有两个获取数据的函数。获取加油站信息和获取汽油信息。
获取加油站信息的函数嵌套着获取汽油信息的函数。
加油站信息缓存设置为60秒到期,加油站里汽油的信息设置为5秒到期。
为了方便测试,值都是Set缓存当前时间的秒。
//获取加油站信息(60秒缓存过期)
public OilStationModel GetOilStation()
{
OilStationModel oilStationModel = cache.GetOrCreate("oilStationModel", entry =>
{
entry.SetAbsoluteExpiration(TimeSpan.FromSeconds(60));
return new OilStationModel
{
OilStationName = $@"加油站名称:{DateTime.Now.Second}",
Oil = GetOil()
};
});
return oilStationModel;
}
//获取加油站中的汽油的信息(5秒缓存过期)
public OilModel GetOil()
{
OilModel oilModel = cache.GetOrCreate("oilModel", entry =>
{
entry.SetAbsoluteExpiration(TimeSpan.FromSeconds(5));
return new OilModel
{
OilName = $@"汽油型号:{DateTime.Now.Second}"
};
});
return oilModel;
}
最后有一个调用的接口,获取加油站的信息:
//缓存域实现缓存依赖
public ActionResult CacheZone()
{
OilStationModel oilStationModel = GetOilStation();
return JsonResult(oilStationModel);
}
调用接口,由于在第2S时调用的接口,可以看到加油站名称和汽油型号都是2。
接下来6秒后再次调用接口,获取加油站信息,按照加油站信息60S过期的策略,理论上应该取得刚才的加油站信息。
加油站名称和汽油型号应该还是2。
但是实际上,加油站名称和汽油型号都是8。
这就是缓存依赖实现的功能。由于依赖项(汽油型号)的缓存过期,使得自身(加油站)的缓存也过期。