2012-01-24 37 views
4

有人可以幫我嗎?我有以下代碼來存儲和修復catch,但是,它不起作用。即使我在slidingExpiration中將緩存設置爲14天,緩存也會過期。提前致謝!緩存到期之前它應該

public static List<ReplyDTO> VideoCommentList() 
{ 
    List<ReplyDTO> replyList = new List<ReplyDTO>(); 
    if (HttpRuntime.Cache["videoComment"] == null) 
    { 
     HttpRuntime.Cache.Remove("videoComment"); 
     HttpRuntime.Cache.Insert("videoComment", replyList, null, Cache.NoAbsoluteExpiration, TimeSpan.FromDays(14)); 
    } 
    else 
    { 
     replyList = (List<ReplyDTO>)HttpRuntime.Cache["videoComment"]; 
    } 

    if (replyList.Count > 8) 
    { 
     replyList = replyList.OrderByDescending(x => x.DateCreated).Take(8).ToList(); 
    } 
    else 
    { 
     replyList = replyList.OrderByDescending(x => x.DateCreated).ToList(); 
    } 
    return replyList; 
} 

public static List<ReplyDTO> AddVideoComment(ReplyDTO replyDTO) 
{ 
    List<ReplyDTO> replyList = new List<ReplyDTO>(); 
    replyList = VideoCommentList(); 
    replyList.Add(replyDTO); 
    HttpRuntime.Cache.Insert("videoComment", replyList, null, Cache.NoAbsoluteExpiration, TimeSpan.FromDays(14)); 

    if (replyList.Count > 8) 
    { 
      replyList = replyList.OrderByDescending(x => x.DateCreated).Take(8).ToList(); 
    } 
    else 
    { 
      replyList = replyList.OrderByDescending(x => x.DateCreated).ToList(); 
    } 
    return replyList; 
} 
+0

請仔細閱讀本文檔 - http://msdn.microsoft.com/en-us/library/xsbfdd8c(v=vs.100).aspx – adatapost

回答

6

ASP.net緩存是內存中的,所以如果您的IIS進程或應用程序池回收它將得到清除。您可以檢查以下東西這可能會導致進程

  • 的回收如果修改web.config,IIS關閉舊的情況下,慢慢的流量轉移到一個新的實例,在這個過程中,內存被回收。 如何檢查此:您可以通過檢查AppDomain.IsFinalizingForUnload並在回調期間記錄該情況來檢測此情況。
  • Application Pool Recycling:在IIS中有一個配置,根據該配置,如果IIS進程在指定的時間內處於空閒狀態,它將對其進行回收。你可以在服務器上檢查這個,並增加這個時間或完全禁用循環。
  • 每個進程都會限制它可以消耗多少內存,如果你在內存中添加太多對象,它會增加IIS的內存消耗,並且在關鍵時間內OS會重新啓動進程。

編輯

在程序中要添加replyList項目緩存,然後做.Take()操作。由於replyList是引用對象,因此如果修改它,它也會在緩存中更新。因此,如果在您的程序中,如果您執行replyList == null它將更新緩存中的項目。

所以修改這樣的代碼,並嘗試

public static List<ReplyDTO> VideoCommentList() 
{ 
    List<ReplyDTO> replyList = new List<ReplyDTO>(); 
    if (HttpRuntime.Cache["videoComment"] == null) 
    { 
     //Call to .Remove is not required 
     //HttpRuntime.Cache.Remove("videoComment"); 
     HttpRuntime.Cache.Insert("videoComment", replyList, null, 
         Cache.NoAbsoluteExpiration, TimeSpan.FromDays(14)); 
    } 
    else 
    { 
     //No need to check count > 8, Take will handle it for you 
     replyList = ((List<ReplyDTO>)HttpRuntime.Cache["videoComment"]) 
         .OrderByDescending(x => x.DateCreated) 
         .Take(8).ToList(); 
    } 
    return replyList; 
} 

public static List<ReplyDTO> AddVideoComment(ReplyDTO replyDTO) 
{ 
    //Read from cache 
    List<ReplyDTO> replyList = ((List<ReplyDTO>)HttpRuntime.Cache["videoComment"]); 
    if(replyList == null) 
     replyList = VideoCommentList(); 
    replyList.Add(replyDTO); 
    HttpRuntime.Cache.Insert("videoComment", replyList, null, Cache.NoAbsoluteExpiration, TimeSpan.FromDays(14)); 

    //Here you are creating a new list, and not referencing the one in the cache 
    return replyList.OrderByDescending(x => x.DateCreated).Take(8).ToList(); 
} 

重要的建議

如果你想查詢的時候,爲什麼你的對象是從緩存中刪除,你可以採取的幫助CacheItemRemovedCallback插入選項。使用此參數和CacheItemRemovedReason參數,可以記錄從緩存中刪除對象的原因。原因

  1. 刪除 - 通過調用InsertRemove方法您的代碼已經從緩存中刪除的項目。
  2. 已過期 - 該項目已從緩存中刪除,因爲它已過期。
  3. 未充分使用 - 當系統內存不足時,它通過從緩存中刪除項目來釋放內存。
  4. DependencyChanged - 由於與其關聯的緩存依賴關係發生更改,因此將項目從緩存中移除。(在你的情況下,它是無效的)

希望這個信息可以幫助你。

+0

嗨阿馬爾,我沒有編輯任何文件。我並不認爲IIS池正在循環使用,因爲它只發生在分鐘內。這是一個新的網站,因此,我現在沒有得到很多流量。內存不應該是一個問題。還有什麼你能想到的?謝謝 – Jack

+0

您是否檢查App Pool Recycle時間?你是怎麼知道緩存被刷新的,你沒有任何'CacheItemRemovedCallback'。 –

+1

是的,我確實使用了CacheItemRemovedCallback。我得到了「2-Removed」作爲緩存被刪除的原因。但是,我懇求對象引用是這裏的問題。非常感謝你的答覆。 – Jack

0

緩存在內存中,並且在您的應用程序回收時過期。我猜你正在開發計算機上評估這種情況,因爲流量較低或文件編輯導致應用程序回收。

+0

西蒙您好,感謝答覆。實際上,這是一個新的網站和共享主機環境。在測試時,我幾乎沒有任何流量,另外,在此期間我沒有編輯文件。 – Jack

+0

humm ..共享虛擬主機你說的?共享主機用於關閉閒置一段時間的應用程序域,它們會在首次調用時重新激活。也許值得看看AppDomain已經存在多久了http://stackoverflow.com/questions/4056635/programmatically-find-when-the-asp-net-worker-process-and-app-domain-last -starte – vtortola

1

爲了追蹤您的項目從緩存中刪除的原因,我建議使用HttpRuntime.Cache.Insert方法的不同超載,以允許您指定CacheItemRemovedCallback回調函數。

Cache.Insert Method (String, Object, CacheDependency, DateTime, TimeSpan, CacheItemPriority, CacheItemRemovedCallback)

從你的緩存代碼似乎不錯

除了。但是一旦你改變你的代碼來指定一個回調函數,記錄彈出原因,這可能會讓你更好地理解你的緩存項目爲什麼變得清晰。

和其他大多數答案一樣,我懷疑你的應用程序由於許多原因而被回收/重置。我認爲生產機器上的大多數應用程序至少每天回收一次,特別是在共享主機環境中。所以我猜想你的數據最多隻能保留一天。

+0

太糟糕了,我試圖使用回調原因。當我的緩存消失後,我從中獲得值0。 – Jack

+0

0 = Microsoft.Practices.EnterpriseLibrary.Caching.CacheItemRemovedReason中已過期,但在System.Web.Caching.CacheItemRemovedReason中沒有定義0。出於好奇,你有沒有嘗試將TimeSpan設置爲TimeSpan.FromMinutes(60),然後看它是否立刻過期?也許14天太多了。 – slolife

+0

我會嘗試 – Jack

0

在AddVideoComment()方法,改變緩存項插入線:

HttpRuntime.Cache.Insert("videoComment", replyList, null, Cache.NoAbsoluteExpiration, TimeSpan.FromDays(14),CacheItemPriority.NotRemovable,null); 

而在VideoCommentList()方法,使用:

 if (HttpRuntime.Cache["videoComment"] == null) 
     { 
      replyList = VideoCommentList(); 
      HttpRuntime.Cache.Insert("videoComment", replyList, null, Cache.NoAbsoluteExpiration, TimeSpan.FromDays(14),CacheItemPriority.NotRemovable,null); 
     } 

不需要使用HttpRuntime.Cache.Remove("videoComment");,因爲HttpRuntime.Cache.Insert(將取代現有的緩存項目。

乾杯, DeveloperConcord

相關問題