我有一個通用的緩存訪問方法在一個帶有三個參數的單例類中。C#將鎖對象傳遞到通用緩存訪問方法
- 委託(不帶參數void返回類型)
- 高速緩存標籤
- 旨在阻止併發緩存設置
見下面的鎖定對象:
protected delegate T GetDataMethod<T>();
protected override D GetCachedData<D>(GetDataMethod<D> dataAccessMethod, string cachelabel, object lockObject)
{
if (MemoryCache.Default[cachelabel] == null)
{
lock (lockObject)
{
//Inside the lock, test once again in case the cache object has been set already
if (MemoryCache.Default[cachelabel] == null)
{
umbraco.BusinessLogic.Log.Add(umbraco.BusinessLogic.LogTypes.Debug, -10, cachelabel + " inside lock, cache empty");
D data = default(D);
try
{
data = dataAccessMethod();
}
catch (Exception ex)
{
//Logging
}
MemoryCache.Default.Add(cachelabel, data, GetCacheItemPolicy());
}
}
}
return (D)MemoryCache.Default[cachelabel];
}
每個數據集合都有單獨的鎖對象,它們將緩存設置爲靜態只讀對象。然而,通過將它們傳遞給方法,它們的作用域只存在於方法中,所以鎖定變得無關緊要。
我不能使用'ref',因爲你無法通過ref傳遞一個靜態對象,因爲周圍的類是單例,如果我使得鎖對象不是靜態的,它會影響嗎?如果會,任何人都可以推薦一種更好的方式來處理它,而不使用基於cacheLabel的switch語句?
編輯: 只是爲了清楚起見,該方法足跡:
protected override D GetCachedData<D>(GetDataMethod<D> dataAccessMethod, string cachelabel, ref object lockObject)
將無法正常工作,鎖定的對象是靜態的。我猜這個問題真的是 - 在一個單例中,鎖對象需要是靜態的才能成爲線程安全的? (是的,這是一個線程安全的單身人士)
對你的緩存使用ConcurrentDictionary將緩解你http://msdn.microsoft.com/en-us/library/dd287191.aspx除非你的問題只是一個思維練習。 –
'它們的作用域只存在於方法內::你的鎖對象是引用類型不是它們嗎?如果是這樣,你能解釋一下你的意思嗎? –
感謝迄今爲止的評論傢伙。你不能通過ref傳遞一個靜態對象,如果我刪除靜態聲明,是不是否定了鎖對象的點?或者,鑑於該方法是在一個單身的否定否定... 這不僅僅是一個思想練習,MemoryCache對象的setter不是線程安全的(就像我發現自己的痛苦),並且數據請求需要花費相當多的時間通過EF,所以我需要鎖定setter方法來防止多個線程填充各種緩存項目(因此兩個階段檢查 - 一次在鎖定之前,一次在鎖定之內) –