如何从ASP.NET Core正确清除IMemoryCache?
我相信此类缺少Clear方法,但是无论如何该如何处理?在我的项目中,我将DocumentRepository的方法缓存了24小时,从数据库中获得了很多行。但是有时候我可以更改数据库,所以我想清除IMemoryCache,因为它有垃圾数据。
答案 0 :(得分:1)
IMemoryCache
确实缺少 Clear()
方法,但是自己实现一个也不难。
public class CacheWrapper
{
private readonly IMemoryCache _memoryCache;
private CancellationTokenSource _resetCacheToken = new();
public CacheWrapper(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
public void Add(object key, object value, MemoryCacheEntryOptions memoryCacheEntryOptions)
{
using var entry = _memoryCache.CreateEntry(key);
entry.SetOptions(memoryCacheEntryOptions);
entry.Value = value;
// add an expiration token that allows us to clear the entire cache with a single method call
entry.AddExpirationToken(new CancellationChangeToken(_resetCacheToken.Token));
}
public void Clear()
{
_resetCacheToken.Cancel(); // this triggers the CancellationChangeToken to expire every item from cache
_resetCacheToken.Dispose(); // dispose the current cancellation token source and create a new one
_resetCacheToken = new CancellationTokenSource();
}
}
基于https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-3.1#cache-dependencies和https://stackoverflow.com/a/45543023/2078975
答案 1 :(得分:1)
有一种简单的方法可以清除它,虽然它可能不适用于所有环境,但在它适用的地方,它运行良好。
如果您通过依赖项注入获取 IMemoryCache
对象,则很有可能您实际上会收到一个 MemoryCache
对象。 MemoryCache
确实有一个名为 Compact()
的方法可以清除缓存。您可以尝试将对象强制转换为 MemoryCache
,如果成功,则调用 Compact
。
示例:
string message;
// _memoryCache is of type IMemoryCache and was set via dependency injection.
var memoryCache = _memoryCache as MemoryCache;
if (memoryCache != null)
{
memoryCache.Compact(1);
message ="Cache cleared";
} else {
message = "Could not cast cache object to MemoryCache. Cache NOT cleared.";
}
答案 2 :(得分:0)
缓存类和接口没有任何方法可以清除两个对象都不可以迭代键,因为它不是列表,并且在ASP.NET Core应用程序中通常使用IDistributedCache
接口作为依赖项,因为它更容易使您以后可以从本地内存缓存更改为分布式缓存(例如memd或Redis)。
相反,如果要使特定行无效,则应通过cache.Remove(myKey)
删除缓存的条目。
当然,这要求您知道要失效的密钥。通常,您通过事件来执行此操作。每次更新数据库中的条目时,都会触发一个事件。此事件将由后台服务捕获,并导致缓存无效。
在本地可以使用任何发布/订阅库来完成。在分布式方案中,您可能要使用分布式缓存的发布/订阅功能(即Redis)。
在查找表(影响许多值的表)的情况下,您可以让服务刷新缓存(即,使用hangfire或quart.net等调度库通过后台任务每5至10分钟刷新一次)。
但是您应该问自己一个问题:如果文档经常更改,将文档缓存24小时真的是一个好主意吗?
加载单个文档是否需要花费大量时间,值得将其缓存24小时?还是较短的时间足够好(15、30、60分钟)?
答案 3 :(得分:0)
要清除您的MemoryCache,只需按如下键删除您的内存缓存:
memoryCache.Remove("your_key");