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

时间:2019-05-26 17:38:31

标签: c# asp.net caching asp.net-core memorycache

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

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

4 个答案:

答案 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-dependencieshttps://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");