2014-12-04 54 views
0

以下測試會間歇性失敗。它在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++; 
     } 
    } 
} 
+0

如果您注意到,AbsoluteExpiration值表示物品將被驅逐的時間量。這意味着這是它保持有效的最短時間,沒有(具有諷刺意味的)絕對時間。這裏的絕對是指這個事實,它不是一個滑動時間限制......並不是它會在那個時刻被驅逐。基本上,該物品可以在到期後的任何時間被驅逐,這可能是幾秒鐘,甚至幾分鐘後。我的測試表明,到期時間可以在0到30秒後的任何時間發生,但可能會更長。 – 2014-12-04 06:48:28

+1

這篇文章似乎表明,內部實現具有某種硬連線20秒計時器:http://stackoverflow.com/questions/12630168/memorycache-absoluteexpiration-acting-strange不知道這是否正確,但它肯定與我在測試結果中看到的相符。 – 2014-12-04 07:08:54

回答

0

因爲這個問題沒有解決方案,所以我抽取了我需要的MemoryCache方法到一個接口中並進行了測試。此時,測試變得無效,因爲我只是測試了我自己的接口實現。

0

我想調用新的CacheEntryUpdateCallback是多餘的。你可以調用: UpdateCallback = new CacheEntryUpdateCallback(this.UpdateItem)改爲