using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Caching;
using Xunit;
namespace Demo.Caching.Test
{
class MemoryCacheManagerTest
{
[Fact]
public void Test()
{
CacheItemPolicy policy = new CacheItemPolicy();
policy.SlidingExpiration = TimeSpan.FromSeconds(1);
MemoryCache.Default.Set("cacheKey4", 4, policy);
Assert.Equal(4, MemoryCache.Default.Get("cacheKey4"));
System.Threading.Thread.Sleep(600);
Assert.Equal(4, MemoryCache.Default.Get("cacheKey4"));
System.Threading.Thread.Sleep(600);
Assert.Equal(4, MemoryCache.Default.Get("cacheKey4"));
// Here I get error
// Expected: 4, Actual: (null)
System.Threading.Thread.Sleep(1000);
Assert.Null(MemoryCache.Default.Get("cacheKey4"));
}
}
}
答案 0 :(得分:4)
可能原因是睡眠是非确定性的。它不会暂停你的线程600毫秒。它暂停的线程至少 600 ms。它可以很好地超过你设定的1秒滑动到期而没有你意识到。
答案 1 :(得分:4)
这是不,正如其他答案所说,由于Thread.Sleep()花费的时间超过预期。
滑动计时器 MemoryCache
似乎非常不精确。我猜这是他们可以避免锁定,并保持缓存的性能。
所以我想我的教训是不要依赖滑动过期来正常工作2秒以下的值。这可能与将PollingInterval
设置为2秒有关。
代码:
var span = TimeSpan.FromSeconds(1); // change as necessary
var sw = new Stopwatch();
var cache = new MemoryCache("testcache");
sw.Start();
cache.Add("test", "hello", new CacheItemPolicy{SlidingExpiration = span});
Console.WriteLine(sw.ElapsedMilliseconds);
for (int i = 0; i < 40; i++)
{
Console.WriteLine(sw.ElapsedMilliseconds + ": " + cache.Get("test"));
Thread.Sleep(50); // change as necessary
}
答案 2 :(得分:0)
我遇到了同样的问题。但实际上问题是@Colin所说的。 Thread.Sleep
正在接管一秒钟。
所以我做了一个更大延迟的测试
[TestMethod]
public void Sliding()
{
MemoryCache.Default.Add("test", 1,
new CacheItemPolicy
{
SlidingExpiration = new TimeSpan(0, 0, seconds: 5)
});
for (int i = 0; i < 15; ++i)
{
Assert.IsNotNull(MemoryCache.Default.Get("test"));
Thread.Sleep(700);
}
}
它过去了。我不确定它是否会一直有效 - 可能不会 - 但我只是确认滑动确实有效。