如何清除 ASP.NET Core 中的 MemoryCache?

CSh*_*ner 9 c# asp.net caching memorycache asp.net-core

如何从 ASP.NET Core 正确清除 IMemoryCache?

我相信这个类缺少 Clear 方法,但无论如何如何处理它?在我的项目中,我将 DocumentRepository 的方法缓存 24 小时,从数据库中获取大量行。但有时我可以更改数据库,所以我想清除 IMemoryCache,因为它有垃圾数据。

Mr.*_*. T 9

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/


Mar*_*uer 5

有一种简单的方法可以清除它,该方法可能不适用于所有环境,但在有效的情况下,效果很好。

如果您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)


Tse*_*eng 1

缓存类和接口没有任何方法来清除它们以迭代键,因为它并不意味着是一个列表,并且在 ASP.NET Core 应用程序中通常使用IDistributedCache接口作为依赖项,因为它更容易允许您稍后从本地内存缓存更改为分布式缓存(例如memd或Redis)。

相反,如果您想要使特定行无效,您应该通过 删除缓存的条目cache.Remove(myKey)

当然,这需要您知道要使其失效的密钥。通常您可以通过事件来做到这一点。每次更新数据库中的条目时,都会触发一个事件。该事件将被后台服务捕获并导致缓存失效。

在本地,这可以通过任何发布/订阅库来完成。在分布式场景中,您可能希望使用分布式缓存(即Redis)的发布/订阅功能。

在查找表的情况下(其中许多值受到影响),您可以让服务刷新缓存(即通过使用调度库(例如hangfire或quart.net)的后台任务每5到10分钟刷新一次)。

家庭作业问题

但您应该问自己一个问题:如果文档经常更改,将其缓存 24 小时真的是一个好主意吗?

加载单个文档是否需要花费如此多的时间,值得将其缓存 24 小时吗?或者更短的时间就足够了(15、30、60 分钟)?


归档时间:

查看次数:

18848 次

最近记录:

4 年,9 月 前