以下測試會間歇性失敗。它在MemoryCache中緩存具有絕對過期時間的項目,以及在項目被移除之前應該調用的更新回調。但是有時在測試結束之前調用回調,有時甚至根本沒有回調。使用MemoryCache進行測試UpdateCallback
有了足夠大的緩衝時間,它總是會被調用至少一次。但是這並不符合我的目的,因爲我要求緩存總是在數據過期之前嘗試更新數據。
現在在我的現實世界中的場景,我不會有10秒到期時間和粒度,但它仍然困擾着我,這個測試間歇性失敗。
任何人都想過爲什麼會發生這種情況?
注意:還間歇性地失敗,60秒到期和5秒緩衝區。
using System;
using System.Runtime.Caching;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class MemoryCacheTest
{
private const double ExpiryInSeconds = 10;
private const double ExpiryBufferInSeconds = 5;
private readonly object updateItemCounterLock = new object();
private int updateItemCounter = 0;
[TestMethod]
public async Task MemoryCacheUpdateTest()
{
// Set item in cache with absolute expiration defined above
MemoryCache cache = MemoryCache.Default;
CacheItem cacheItem = new CacheItem("key", "value");
CacheItemPolicy cacheItemPolicy = new CacheItemPolicy
{
AbsoluteExpiration = DateTimeOffset.Now + TimeSpan.FromSeconds(ExpiryInSeconds),
UpdateCallback = new CacheEntryUpdateCallback(this.UpdateItem)
};
cache.Set(cacheItem, cacheItemPolicy);
// Delay for absolute expiration time + buffer
await Task.Delay(TimeSpan.FromSeconds(ExpiryInSeconds) + TimeSpan.FromSeconds(ExpiryBufferInSeconds));
// Test that the update callback was invoked once
Assert.AreEqual(1, updateItemCounter);
}
// Incrememnts the updateItemCounter
private void UpdateItem(CacheEntryUpdateArguments args)
{
lock (updateItemCounterLock)
{
updateItemCounter++;
}
}
}
如果您注意到,AbsoluteExpiration值表示物品將被驅逐的時間量。這意味着這是它保持有效的最短時間,沒有(具有諷刺意味的)絕對時間。這裏的絕對是指這個事實,它不是一個滑動時間限制......並不是它會在那個時刻被驅逐。基本上,該物品可以在到期後的任何時間被驅逐,這可能是幾秒鐘,甚至幾分鐘後。我的測試表明,到期時間可以在0到30秒後的任何時間發生,但可能會更長。 – 2014-12-04 06:48:28
這篇文章似乎表明,內部實現具有某種硬連線20秒計時器:http://stackoverflow.com/questions/12630168/memorycache-absoluteexpiration-acting-strange不知道這是否正確,但它肯定與我在測試結果中看到的相符。 – 2014-12-04 07:08:54