我的问题与这个类似,但答案只解释了为什么事情会这样发生,而不是如何真正实现期望的解决方案。
现在,在定义
var options = new MemoryCacheEntryOptions()
{
// After x minutes of non-access, remove
SlidingExpiration = TimeSpan.FromMinutes(x),
}
.RegisterPostEvictionCallback(OnCacheItemRemoved);
仅在某个时间点>访问时才会删除 cacheItem 。这意味着,如果我在此之后不再访问该项目,它也不会从缓存中删除。t1
t0 + x'
是的,我可以设置绝对过期时间,但这会推翻滑动窗口。如果我希望它在仍被访问时留在内存中,那么它会因绝对过期而被驱逐。我想要的是一个简单的滑动窗口,一旦项目在x
几分钟内没有被访问,它就会自动被驱逐。我希望有一个内部计时器来处理这个问题。出于性能原因,它不需要每秒运行一次,一分钟一次对我来说就足够了。
我也没有看到任何关于如何检查驱逐的配置。
编辑
在为 DI 添加 MemoryCache 时,实际上有一个选项ExpirationScanFrequency
services.AddMemoryCache(options => {
// Check for expired cache items once a minute
options.ExpirationScanFrequency = TimeSpan.FromMinutes(1);
});
但这似乎不起作用。几分钟后,即使没有任何内容访问我的回调,它仍然没有被调用。1
目前 X 设置为。
这不是完全正确的表述。正如其中一个答案中的链接所解释的那样,缓存上的任何活动都可能导致驱逐,例如向缓存中添加新项目,甚至读取另一个键:
查看源代码中的用法
StartScanForExpiredItemsIfNeeded
- 它在几种方法中被调用,例如Remove
、SetEntry
和。TryGetValue
EntryExpired
例如你可以玩以下游戏:
除了一些像下面这样的技巧之外,你在这里能做的事情不多:
MemoryCache.Compact
手动调用(例如(cache as MemoryCache)?.Compact(0.01)
下面是启动计时器检查过期物品的代码示例,可能适合您的需要。
每 5 秒缓存中的项目就会过期一次 - 您可以通过更改以下两行来更改时间长度:
在示例中,创建了一个内存缓存,并添加了 3 个项目,每个项目如果在滑动过期时间范围内未访问,则会过期: