2011-06-20 47 views
4

我有一個很少使用的字典,它幾乎不會被讀取或更新,因爲單個項目會引發事件並將其結果與事件參數一起返回。事實上,線程總是要用同一個線程更新。我正在考慮添加一個簡單的鎖來保證安全。我想知道是否可以將鎖放在get訪問器中。這是否工作?我可以鎖定get accessor中的集合嗎?

 Dictionary<string,Indicator> indicators = new Dictionary<string,Indicator>(); 
     Dictionary<string, Indicator> Indicators 
     { 
      get 
      { 
       lock (indicators) 
       { 
        return indicators; 
       } 
      } 
     } 

     public void AddIndicator(Indicator i) 
     { 
      lock (indicators) 
      { 
       indicators.Add(i.Name, i); 
      } 
     } 

回答

6

這沒有做任何特別有用的事,沒有。

特別是,如果您有:

x = foo.Indicators["blah"] 

那麼索引將被執行線程持有鎖......所以它不是線程安全的。這樣想着上面的代碼:

Dictionary<string, Indicator> indicators = foo.Indicators; 
// By now, your property getter has completed, and the lock has been released... 
x = indicators["blah"]; 

你是否需要比通過索引訪問它的其他集合做什麼?如果沒有,你可能想只是一個方法替換屬性:

public Indicator GetIndicator(string name) 
{ 
    lock (indicators) 
    { 
     return indicators[name]; 
    } 
} 

(您可能需要使用TryGetValue而不是等 - 這取決於你想要達到的)

個人我寧願使用對私有和未使用的鎖對象的引用,而不是鎖定集合引用,但這是一個單獨的問題。

正如其他地方提到,ConcurrentDictionary是你的朋友如果你使用.NET 4中,但當然是:(

0

簡答:是的。
爲什麼不應該這樣工作,但正如Jon所提到的那樣,它在使用索引時沒有像預期那樣鎖定?

+3

這不是「數組訪問」 - 它是一個索引器。但更重要的是,當你獲得參考信息後,鎖定將會被釋​​放*無論你如何處理它*。 –

+0

@jon:感謝提示,我正在編程PHP,因爲它被稱爲數組訪問...... – ChrFin

4

除了喬恩的投入,我會說沒有之前是不可用反正鎖定集合indicators本身,從MSDN:實例上鎖定時

要小心,在C# 例如鎖(本)或Visual Basic 的SyncLock(Me)中如果其他 代碼在你的應用程序, 外部類型,鎖定對象, 可能發生死鎖。

建議使用專用的object實例進行鎖定。還有其他的地方,這裏有更多的細節和原因,甚至在這裏,如果你有時間,你應該關心搜索信息。

+0

我剛剛添加了一些類似於我自己的答案:) –

+0

@Jon:當然不認爲你會提供良好的報道 - 只是把我自己的脖子伸出一點! –

+0

我並沒有試圖譴責你的答案 - 只是評論時間的巧合:) –

相關問題