2013-05-13 40 views
14

我想使用System.Runtime.Caching.MemoryCache來緩存我的一些對象。我想確保對象每天刷新一次(絕對到期),但如果它在最近一小時內沒有被使用(滑動到期),我也想使其到期。 我嘗試做:組合滑動和絕對過期

object item = "someitem"; 
var cache = MemoryCache.Default; 
var policy = new CacheItemPolicy(); 
policy.AbsoluteExpiration = DateTime.Now.AddDays(1); 
policy.SlidingExpiration = TimeSpan.FromHours(1); 
cache.Add("somekey", item, policy); 

但我發現了一個「ArgumentException的」與「AbsoluteExpiration必須DateTimeOffset.MaxValue或SlidingExpiration必須TimeSpan.Zero。」

回答

9

您可以通過使用CacheEntryChangeMonitor實現兩種方案緩存過期。 插入一個沒有絕對過期信息的緩存項目,然後用這個項目創建一個空的monitorChange並將它與第二個緩存項目連接起來,在那裏你將實際保存一個slidingTimeOut信息。

 object data = new object(); 
     string key = "UniqueIDOfDataObject"; 
     //Insert empty cache item with absolute timeout 
     string[] absKey = { "Absolute" + key }; 
     MemoryCache.Default.Add("Absolute" + key, new object(), DateTimeOffset.Now.AddMinutes(10)); 

     //Create a CacheEntryChangeMonitor link to absolute timeout cache item 
     CacheEntryChangeMonitor monitor = MemoryCache.Default.CreateCacheEntryChangeMonitor(absKey); 

     //Insert data cache item with sliding timeout using changeMonitors 
     CacheItemPolicy itemPolicy = new CacheItemPolicy(); 
     itemPolicy.ChangeMonitors.Add(monitor); 
     itemPolicy.SlidingExpiration = new TimeSpan(0, 60, 0); 
     MemoryCache.Default.Add(key, data, itemPolicy, null); 
+0

我認爲這是一個很好的解決方法,如果它工作。謝謝 – Andres 2013-05-16 20:44:35

-2

DateTime.Now.AddDays(1)不會返回DateTimeOffset,而是返回DateTime(AddDays())。

所以這很可能是一個無效的參數。

因此,請嘗試DateTimeOffset.Now.AddDays(1)DateTimeOffset)。

+3

-1:有一個[隱含的運營商(http://msdn.microsoft.com/en-us/library /system.datetimeoffset.op_implicit.aspx)從「DateTime」轉換爲「DateTimeOffset」。 – 2013-05-13 16:27:15

+0

不知道。感謝更新。 – ThaMe90 2013-05-14 06:40:37

3

與ILSpy快速反射調用MemoryCache.Add

if (policy.AbsoluteExpiration != ObjectCache.InfiniteAbsoluteExpiration && policy.SlidingExpiration != ObjectCache.NoSlidingExpiration) 
    { 
     throw new ArgumentException(R.Invalid_expiration_combination, "policy"); 
    } 

所以,絕對的結合和可調過期,本身不支持時,顯示此代碼。

你應該把自己變成一個自定義的實現。

2

一點點額外的註釋,dieguitofernandez答案(這是順便說一句,一個很好的解決方案):

的ChangeMonitor不是在確切時刻到達則absoluteExpiration菲林,因爲過期不每秒檢查一次。可能需要幾秒鐘才能通知第二個緩存項目。 以1天爲AbsoluteExpiration並不重要,但如果你需要兩個期限是確切的(就像我一樣),你必須先使用鍵和絕對鍵。

if (cache.Contains("Absolute" + key) && cache.Contains(key)) 

用這種方法可以立即檢查兩個到期日,並且您可以確定該項目未過期。

(因爲我是新來的,我可以張貼此作爲評論,對不起!)