.Net Core MemoryCache PostEvictionCallback无法正常工作

时间:2017-03-01 15:14:59

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

我在Microsoft.Extensions.Caching.Memory.MemoryCache中设置了具有滑动过期的缓存项。 我想在每次缓存项到期时触发回调,但是在我查询缓存中过期的缓存项之前,不会触发回调。

以下是代码:

destroy

2 个答案:

答案 0 :(得分:7)

要添加接受答案和评论,您可以使用过期的取消令牌强制缓存过期并自动逐出。

int expirationMinutes = 60;
var expirationTime = DateTime.Now.Add(expirationMinutes);
var expirationToken = new CancellationChangeToken(
    new CancellationTokenSource(TimeSpan.FromMinutes(expirationMinutes + .01)).Token);

var cacheEntryOptions = new MemoryCacheEntryOptions()
         // Pin to cache.
         .SetPriority(CacheItemPriority.NeverRemove)
         // Set the actual expiration time
         .SetAbsoluteExpiration(expirationTime)
         // Force eviction to run
         .AddExpirationToken(expirationToken)
         // Add eviction callback
         .RegisterPostEvictionCallback(callback: CacheItemRemoved, state: this); 

`

缺乏内置的计时器行为,旧的曾经有过,应该是设计的,这就是它所建议的。请参阅:https://github.com/aspnet/Caching/issues/248

答案 1 :(得分:3)

这种情况正在发生,因为在您查询该项目并检查到期时,该项目不会被逐出

(来自MemoryCacheStore.Get(MemoryCacheKey key)的来源)

    internal MemoryCacheEntry Get(MemoryCacheKey key) {
        MemoryCacheEntry entry = _entries[key] as MemoryCacheEntry;
        // has it expired?
        if (entry != null && entry.UtcAbsExp <= DateTime.UtcNow) {
            Remove(key, entry, CacheEntryRemovedReason.Expired);
            entry = null;
        }
        // update outside of lock
        UpdateExpAndUsage(entry);
        return entry;
    }

或由于记忆压力而在内部调用Trim()

(来自TrimInternal(int percent)的来源)

/*SNIP*/
        trimmedOrExpired = _expires.FlushExpiredItems(true);
        if (trimmedOrExpired < toTrim) {
            trimmed = _usage.FlushUnderUsedItems(toTrim - trimmedOrExpired);
            trimmedOrExpired += trimmed;
        }
/*SNIP*/

如果您的系统目前内存不足以触发修剪,那么唯一可以驱逐项目的时间是尝试检索它们。