.Net Core MemoryCache PostEvictionCallback无法正常工作 [英] .Net Core MemoryCache PostEvictionCallback not working properly
问题描述
我已经在Microsoft.Extensions.Caching.Memory.MemoryCache中设置了具有过期时间的缓存项。
我想在每次缓存项过期时触发回调,但是直到我查询缓存中已过期的缓存项时才触发回调。
I have set cache items with sliding expiration in a Microsoft.Extensions.Caching.Memory.MemoryCache. I want to trigger a callback everytime a cache item expires, but callback isn't triggered until I query the cache for the expired cache item.
这里是代码:
using System;
using Microsoft.Extensions.Caching.Memory;
namespace Memcache
{
public class Program
{
private static MemoryCache _cache;
private static int _cacheExpSecs;
public static void Main(string[] args)
{
_cache = new MemoryCache(new MemoryCacheOptions());
_cacheExpSecs = 2;
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromSeconds(_cacheExpSecs))
.RegisterPostEvictionCallback(callback: EvictionCallback);
_cache.Set(1, "One", cacheEntryOptions);
_cache.Set(2, "Two", cacheEntryOptions);
var autoEvent = new System.Threading.AutoResetEvent(false);
System.Threading.Timer timer = new System.Threading.Timer(checkCache, autoEvent, 1000, 6000);
Console.Read();
}
private static void checkCache(Object o)
{
if(_cache.Get(1)!=null)
{
Console.WriteLine(string.Format(@"checkCache: Cache with key {0} will be removed manually and will trigger the callback.", 1));
_cache.Remove(1);
}
else
{
Console.WriteLine(string.Format("checkCache: Cache with key {0} is expired.", 1));
}
if(_cache.Get(2) != null)
{
Console.WriteLine(string.Format("checkCache: Cache with key {0} will expire in {1} seconds, but won't trigger the callback until we check it's value again.", 2, _cacheExpSecs));
}
else
{
Console.WriteLine(string.Format("checkCache: Cache with key {0} is expired.", 2));
}
}
private static void EvictionCallback(object key, object value, EvictionReason reason, object state)
{
Console.WriteLine();
Console.WriteLine("/*****************************************************/");
Console.WriteLine(string.Format("/* EvictionCallback: Cache with key {0} has expired. */", key));
Console.WriteLine("/*****************************************************/");
Console.WriteLine();
}
}
}
推荐答案
之所以发生这种情况,是因为直到您查询该项目并检查到期之后,该项目才被逐出
It is happening because the item is not evicted till you query for the item and it checks the expiration
(来自 MemoryCacheStore.Get(MemoryCacheKey键)
)
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()
由于内存压力在内部被调用
or when Trim()
is called internally due to memory pressure
(来自 TrimInternal(int percent)
)
/*SNIP*/
trimmedOrExpired = _expires.FlushExpiredItems(true);
if (trimmedOrExpired < toTrim) {
trimmed = _usage.FlushUnderUsedItems(toTrim - trimmedOrExpired);
trimmedOrExpired += trimmed;
}
/*SNIP*/
如果系统当前不低足够的内存来触发修整,则只有在尝试检索项目时才将其逐出。
If your system is not currently low enough on memory to trigger a trim then the only time items will be evicted is when they are attempted to be retrieved.
这篇关于.Net Core MemoryCache PostEvictionCallback无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!