2009-06-29 129 views
2

我有一些麻煩讓我的緩存以我想要的方式工作。ASP.NET持久緩存(「懶惰加載」式?)

問題: 的檢索請求的數據是非常耗時的過程。如果使用標準的ASP.NET緩存,一些用戶將會用「檢索」數據。這是不可接受的。

解決方案?: 數據是100%流量並不是非常重要。我想在更新另一個線程中的緩存數據的同時服務舊的無效數據,以便將來的請求使用新數據。我認爲數據需要以某種方式持續存在,以便能夠在應用程序重新啓動後爲第一個用戶提供服務,而無需用戶執行「命中」操作。

我已經做了一個解決方案,做了一些上述,但我想知道是否有一個「最佳實踐」的方式或有一個緩存框架已經支持這種行爲?

回答

1

我用內存中的Dictionary/Hashtable創建了自己的解決方案,作爲實際緩存的副本。當一個方法調用來自緩存請求對象並且它不存在但存在於內存中時,內存存儲對象被返回,並且使用委託方法觸發一個新線程來更新內存和緩存中的對象。

1

,你可以聽,當緩存項被刪除,然後處理,

public void RemovedCallback(String k, Object v, CacheItemRemovedReason r) 
{ 
    // Put Item Back IN Cache, (so others can use it until u have finished grabbing the new data) 

    // Spawn Thread to Go Get Up To Date Data 

    // Over right Old data with new return... 
} 
全球ASAX

protected void Application_Start(object sender, EventArgs e) 
{ 
    // Spawn worker thread to pre-load critical data 
} 

喔...我不知道這是不是最好的做法,我只是認爲這將是光滑的〜 好運〜

+0

好主意..我沒有想到這一點。 但是,使用這種解決方案,訪問該網站的第一個用戶仍然需要更新緩存的「命中」。另外,因爲我使用內聯代理來獲取數據,所以我不知道如何在RemovedCallback中重新運行委託。 – hakksor 2009-06-30 06:44:22

+0

對不起,我忘了解決這個部分。在你的Global.Asax應用程序啓動中,產生一個線程,向所需的數據發出「假」請求。這種方式已經在工作或者已經完成了第一個要求。 – BigBlondeViking 2009-06-30 13:02:32

3

有工具可以做到這一點,例如微軟ISA服務器(可能有點貴/矯枉過正)。

您可以使用Enterprise Libary Caching將其緩存在內存中。讓用戶從緩存中讀取數據,並讓其他頁面更新緩存,這些其他頁面應定期調用,因爲您需要保持數據更新。

0

是的,當你的應用程序啓動時,你可以緩存最頻繁訪問的數據,但這仍然意味着第一個觸發的用戶會按照你的說法(假設inproc緩存)觸發它。

0

我在這種情況下所做的是使用db中的CacheTable來緩存最新數據,並在表中刷新數據並運行後臺作業(在共享環境中使用windows服務,您也可以使用線程) 。

顯示用戶空白屏幕的可能性非常小。我通過在asp.net緩存中緩存1分鐘來消除這種情況。

不知道這是不是一個糟糕的設計,但它在高度使用的網站上沒有問題的工作很好。

1

您可以使用.NET中內置的CacheTimer類很容易地做到這一點。計時器在單獨的線程上運行。

而且我實際上編寫了一個非常小的包裝庫,名爲WebCacheHelper,它在重載構造函數中公開此功能。該庫也可作爲圍繞Cache對象的強類型包裝。

這裏是你如何能做到這一點的例子...

public readonly static WebCacheHelper.Cache<int> RegisteredUsersCount = 
    new WebCacheHelper.Cache<int>(new TimeSpan(0, 5, 0),() => GetRegisteredUsersCount()); 

這有懶加載方面它那裏GetRegisteredUsersCount()將在調用線程是RegisteredUsersCount第一次被訪問的即時執行。但是,之後它每5分鐘在後臺線程上執行。這意味着只有等待時間較慢的用戶纔會成爲第一個用戶。

然後獲得該值就像參考RegisteredUsersCount.Value一樣簡單。