为什么MemoryCache中的滑动过期行为如此奇怪

本文关键字:过期 MemoryCache 为什么 | 更新日期: 2023-09-27 17:57:38

我不明白在.NET 4.0的System.Runtime.Caching.MemoryCache中滑动过期应该如何工作。

根据文件,过期时间跨度是"在从缓存中逐出缓存项之前,必须访问缓存项的时间跨度。"

但是,以下单元测试失败:

private const string AnyKey = "key";
private const string AnyValue = "value";
private readonly TimeSpan timeout = TimeSpan.FromSeconds(0.5);
private void WaitSixtyPercentOfTheTimeout()
{
    Thread.Sleep(TimeSpan.FromSeconds(timeout.TotalSeconds*0.6));
}
[Test]
public void Get_RefreshesTimeoutOfSlidingExpiration()
{
    var cache = MemoryCache.Default;
    cache.Set(AnyKey, AnyValue, new CacheItemPolicy {SlidingExpiration = timeout});
    WaitSixtyPercentOfTheTimeout();
    cache[AnyKey].Should().Be(AnyValue);
    WaitSixtyPercentOfTheTimeout();
    cache[AnyKey].Should().Be(AnyValue);
}
private void UpdateCallback(CacheEntryUpdateArguments arguments)
{
}

巧合的是,我做了一个小改动,解决了这个问题。然而,现在有人认为这是一个bug或功能吗?

一旦设置了UpdateCallBack,过期将按预期工作:

// [...]
[Test]
public void Get_RefreshesTimeoutOfSlidingExpiration()
{
    var cache = MemoryCache.Default;
    cache.Set(AnyKey, AnyValue, new CacheItemPolicy {SlidingExpiration = timeout, UpdateCallback = UpdateCallback});
    WaitSixtyPercentOfTheTimeout();
    cache[AnyKey].Should().Be(AnyValue);
    WaitSixtyPercentOfTheTimeout();
    cache[AnyKey].Should().Be(AnyValue);
}
private void UpdateCallback(CacheEntryUpdateArguments arguments)
{
}

为什么MemoryCache中的滑动过期行为如此奇怪

延长超时似乎可以解决问题。让它2秒在我的机器上工作:

private readonly TimeSpan timeout = TimeSpan.FromSeconds(2);

我想目前的缓存机制在时间上不是很准确,但在实践中,无论如何你都不会保持缓存半秒钟。