![](/img/trans.png)
[英]Frequent, cancellable, asynchronous large-file read operations (.NET 4.0)
[英]Concurrent collection to use for frequent read and rare write operations (.NET)
我想在我的Web應用程序中創建一個緩存,這將允許頂層(MVC)持久保存從底層(服務和數據庫)檢索的某些值,以避免對它的不必要的請求。 我希望在網站的每個頁面上存儲我想要存儲在緩存中的數據,因此該緩存旨在顯着減少請求量。 這個想法是很多線程將從集合中讀取數據,而一個線程將清除它並在緩存過期后檢索新數據。 這意味着該集合將用於頻繁閱讀和罕見的書寫操作。
對我來說,問題是為這些目的選擇合適的類。 我已經閱讀了.NET 4中引入的System.Collections.Concurrent
的並發類集。我絕對不需要使用ConcurrentQueue
或ConcurrentStack
,但我必須在BlockingCollection
, ConcurrentBag
和ConcurrentDictionary
之間進行選擇。
在這種情況下, ConcurrentBag
似乎是最好的解決方案。 但是,我在這篇文章中讀到了並發字典
...對於讀取操作完全沒有鎖定。 通過這種方式,它針對從字典中讀取最頻繁操作的情況進行了優化。
那么最好的解決方案是使用ConcurrentDictionary<int, MyTypeOfObj>
嗎? 或者我可能根本不需要並發類型,簡單的List
會完成這項工作嗎? 可能,如果我可以以某種方式鎖定緩存更新時的操作,它會這樣做。 但是使用簡單的lock
是不可取的。
任何建議和解釋都表示贊賞。
緩存用於存儲插座的地圖點。 這組插座非常穩定,但應該有一個UI來添加它們,因此插入操作非常少見。 在超時后從底層執行整個集合然后執行插入操作可能更容易。 也不需要搜索,閱讀意味着簡單的枚舉。
根據對問題的評論,我決定使用MemoryCache
(事實上,我並不是很清楚)。 由於我不需要為數據分離緩存實例,因此我使用保存在Default
屬性中的緩存:
除非需要,否則不要創建MemoryCache實例。 (...)如果在應用程序中只創建一個緩存實例,請使用默認緩存,並在需要訪問緩存時從Default屬性獲取對它的引用。
我通過以下方式初始化緩存:
private static MemoryCache _instance = MemoryCache.Default;
public static IEnumerable<MyDto> GetDtos()
{
var result = _instance.Get(SOME_NAME);
if (result == null)
result = InitializeCache();
return result;
}
沒有用於閱讀操作的鎖。 然后,在InitializeCache
鎖定一個以防止多個請求:
private static IEnumerable<MyDto> InitializeCache()
{
lock (_monitor) // here all threads but one will stop
{
var result = _instance.Get(SOME_NAME); // in case this thread is not the first who entered the lock
if (result == null)
{
result = RetrieveSomeHowYourDataFromDbOrService();
if (result == null)
return null; // or exception
_instance.Set(SOME_NAME, result, new CacheItemPolicy { AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddSeconds(TIMEOUT)), RemovedCallback = CacheClearedCallback});
}
return (IEnumerable<MyDto>)result;
}
}
使用CacheItemPolicy
允許清除過時的項目並從回調中再次檢索項目:
private static void CacheClearedCallback(CacheEntryRemovedArguments arguments)
{
InitializeCache();
}
在這種情況下,緩存將在沒有來自消費者的請求的情況下進行更新(而不是在應用程序中的第一個請求中進行)。
可能,這不是有史以來最好的解決方案,但希望可以幫助某人,也許可以從一開始。 感謝您提示和評論。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.