CSh*_*ner 9 c# asp.net caching memorycache asp.net-core
如何从 ASP.NET Core 正确清除 IMemoryCache?
我相信这个类缺少 Clear 方法,但无论如何如何处理它?在我的项目中,我将 DocumentRepository 的方法缓存 24 小时,从数据库中获取大量行。但有时我可以更改数据库,所以我想清除 IMemoryCache,因为它有垃圾数据。
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();
}
}
Run Code Online (Sandbox Code Playgroud)
基于https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-3.1#cache-dependencies和/sf/answers/3188011641/
有一种简单的方法可以清除它,该方法可能不适用于所有环境,但在有效的情况下,效果很好。
如果您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.";
}
Run Code Online (Sandbox Code Playgroud)
缓存类和接口没有任何方法来清除它们以迭代键,因为它并不意味着是一个列表,并且在 ASP.NET Core 应用程序中通常使用IDistributedCache接口作为依赖项,因为它更容易允许您稍后从本地内存缓存更改为分布式缓存(例如memd或Redis)。
相反,如果您想要使特定行无效,您应该通过 删除缓存的条目cache.Remove(myKey)。
当然,这需要您知道要使其失效的密钥。通常您可以通过事件来做到这一点。每次更新数据库中的条目时,都会触发一个事件。该事件将被后台服务捕获并导致缓存失效。
在本地,这可以通过任何发布/订阅库来完成。在分布式场景中,您可能希望使用分布式缓存(即Redis)的发布/订阅功能。
在查找表的情况下(其中许多值受到影响),您可以让服务刷新缓存(即通过使用调度库(例如hangfire或quart.net)的后台任务每5到10分钟刷新一次)。
但您应该问自己一个问题:如果文档经常更改,将其缓存 24 小时真的是一个好主意吗?
加载单个文档是否需要花费如此多的时间,值得将其缓存 24 小时吗?或者更短的时间就足够了(15、30、60 分钟)?
| 归档时间: |
|
| 查看次数: |
18848 次 |
| 最近记录: |