2011-05-05 45 views
14

我在HttpContext.Cache中存儲一個整數值,並且從現在起絕對過期時間爲5分鐘。然而,在等待6分鐘(或更長時間)之後,整數值仍然在高速緩存中(即,即使絕對超時已經過去也不會被除去)。這裏是我使用的代碼:ASP.net緩存絕對過期不起作用

public void UpdateCountFor(string remoteIp) 
{ 
    // only returns true the first time its run 
    // after that the value is still in the Cache 
    // even after the absolute expiration has passed 
    // so after that this keeps returning false 
    if (HttpContext.Current.Cache[remoteIp] == null) 
    { 
     // nothing for this ip in the cache so add the ip as a key with a value of 1 
     var expireDate = DateTime.Now.AddMinutes(5); 
     // I also tried: 
     // var expireDate = DateTime.UtcNow.AddMinutes(5); 
     // and that did not work either. 
     HttpContext.Current.Cache.Insert(remoteIp, 1, null, expireDate, Cache.NoSlidingExpiration, CacheItemPriority.Default, null); 
    } 
    else 
    { 
     // increment the existing value 
     HttpContext.Current.Cache[remoteIp] = ((int)HttpContext.Current.Cache[remoteIp]) + 1; 
    } 
} 

我第一次運行UpdateCountFor(「127.0.0.1」)它插入1與鍵「127.0.0.1」的高速緩存和5分鐘從現在絕對過期如預期。隨後的每一次運行都會增加緩存中的值。但是,等待10分鐘後,它會繼續增加緩存中的值。該值永不過期,永遠不會從緩存中刪除。這是爲什麼?

這是我的理解,絕對到期時間意味着該項目將被刪除大約在那個時候。難道我做錯了什麼?我誤解了什麼嗎?

我期待值5分鐘後從緩存中刪除,但它留在那裏,直到我重建項目。

這是所有在我的本地機器上運行的.NET 4.0。

+0

您的web.config中是否有任何奇怪的緩存配置設置? – 2011-05-06 16:49:51

+0

不,我有默認的web.config – smoak 2011-05-06 17:37:56

回答

12

事實證明,這條線:

HttpContext.Current.Cache[remoteIp] = ((int)HttpContext.Current.Cache[remoteIp]) + 1; 

刪除以前的值,並用NO絕對或滑動過期時間重新插入值。爲了解決這個問題,我不得不創建一個幫助類,並使用它像這樣:

public class IncrementingCacheCounter 
{ 
    public int Count; 
    public DateTime ExpireDate; 
} 

public void UpdateCountFor(string remoteIp) 
{ 
    IncrementingCacheCounter counter = null; 
    if (HttpContext.Current.Cache[remoteIp] == null) 
    { 
     var expireDate = DateTime.Now.AddMinutes(5); 
     counter = new IncrementingCacheCounter { Count = 1, ExpireDate = expireDate }; 
    } 
    else 
    { 
     counter = (IncrementingCacheCounter)HttpContext.Current.Cache[remoteIp]; 
     counter.Count++; 
    } 
    HttpContext.Current.Cache.Insert(remoteIp, counter, null, counter.ExpireDate, Cache.NoSlidingExpiration, CacheItemPriority.Default, null); 
} 

這會得到解決的問題,並讓計數器在絕對正確的時間到期,同時仍然能夠更新它。

+0

這是API太有幫助的情況。而不是強迫你使用索引器的存儲機制,因爲你看到導致奇怪 – 2011-05-09 12:46:11

+1

我同意。我最終使用[ilspy](http://wiki.sharpdevelop.net/ilspy.ashx)來查看所有這些。 – smoak 2011-05-09 22:30:02

3

嘗試使用DateTime.UtcNow來計算您的超時期限而不是datetime.Now。您可能正在運行到下面描述的問題:

absoluteExpiration類型: 的System.DateTime在其中插入 對象過期併除去 從高速緩存中的時間。 爲避免可能的 問題與本地時間如 從標準時間到夏令時 時間,使用UtcNow而不是Now爲 此參數值。如果您使用的是 絕對過期,那麼slidingExpiration參數必須爲 NoSlidingExpiration。

+0

改變它使用DateTime.UtcNow.AddMinutes(5);沒有工作:( – smoak 2011-05-05 19:09:09

+0

Bummer我認爲你的代碼是正確的,它看起來是正確的,它什麼時候從緩存中刪除?你可以添加一個回調到cache.insert來找出它何時被刪除。也許這會讓你知道觸發它的一些線索。 – 2011-05-05 19:22:31

+0

就是這樣,它根本不會從緩存中移除。這是我遇到的問題。我期待它在5分鐘後被刪除,但是它會一直保留在那裏,直到我重建項目。 – smoak 2011-05-05 19:50:40

0

有一個比smoak發佈更簡單的答案。使用該示例作爲起點,下面的更新代碼起作用,並且不需要重新插入。這起作用的原因是因爲類是引用類型。因此,當您更新類實例內的計數器時,它不會導致緩存觸發更新。

public class IncrementingCacheCounter 
{ 
    public int Count; 
} 

public void UpdateCountFor(string remoteIp) 
{ 
    IncrementingCacheCounter counter = null; 
    if (HttpContext.Current.Cache[remoteIp] == null) 
    { 
     counter = new IncrementingCacheCounter { Count = 1}; 
     HttpContext.Current.Cache.Insert(remoteIp, counter, null, DateTime.Now.AddMinutes(5), Cache.NoSlidingExpiration, CacheItemPriority.Default, null); 
    } 
    else 
    { 
     counter = (IncrementingCacheCounter)HttpContext.Current.Cache[remoteIp]; 
     counter.Count++; 
    } 
}