2012-03-30 56 views
2

我知道C#字典在添加,讀取和刪除元素時不是線程安全的;但是,如果另一個線程正在寫入,讀取和從字典中刪除,您可以以線程安全的方式訪問C#字典的Count屬性嗎?多線程訪問C#字典

+2

您是否期望它返回正確的值? – 2012-03-30 22:15:13

+0

或者只是使用一個ConcurrentDictionary ... http://msdn.microsoft.com/en-us/library/dd287191.aspx – 2012-03-30 22:17:57

回答

0

您可以將字典創建爲靜態只讀對象,並在修改它時使用lock ...應該處理大多數問題,我想。

2

由於屬性是一個方法調用引擎蓋下所以真的情況並不像乍一看那麼簡單。

  • T1:訪問Count屬性
  • T1:get_Count()調用(某種JMP/GOTO ASM指令的)
  • T1:讀變量表示若干項目== 1
  • T2的:addign一個新的項目,真正的計數變成2
  • T1:返回1但真的已經有兩個項目

因此,如果應用程序邏輯依賴於Count財產價值 - 理論上你可能會以race condition結尾。

+0

因爲不能直接寫入屬性,所以不能很好地同時讀取它。後者不遵循前者。這是危險的想法。 – usr 2012-03-30 22:24:27

+0

right我正在寫我的答案,最初我的想法是錯的,你是對的 – sll 2012-03-30 22:25:46

4

它應該是線程安全的,它不會爆炸,但我相當肯定它不是線程安全的,它可能不會給你正確的計數,因爲其他線程操縱字典。

[編輯:正如usr指出的,只是因爲它目前在這個級別的線程安全並不意味着它會繼續如此。你沒有保證]

0

根據你想達到什麼,你可以保護字典ReaderWriterLockSlim。通過這種方式,您可以更快地讀取數據,並且只在執行變異操作時鎖定字典。

0

不是假設相反,我去和反射看着它:

public int Count 
{ 
    get 
    { 
     // count and freeCount are local fields 
     return (this.count - this.freeCount); 
    } 
} 

所以,是的,它是在字典中的對象,訪問也不會造成腐敗「線程安全的」。也就是說,我不確定我是否可以想到任何使用情況下,如果字典正在被另一個線程訪問,那麼獲得任何準確度的計數都很重要。

+0

'if(dict.Count == 1)'永遠不會*安全地工作 – 2012-03-30 22:34:11

+0

@L。你是否在我的回答結尾處閱讀了該段落? – 2012-03-30 22:35:11

+0

您是否認爲我只是在未閱讀完整答案的情況下撰寫評論? 「我可以想到,如果字典被另一個線程訪問,任何準確的計數都很重要。」正確但受限於你的想象力。 – 2012-03-30 22:44:32

1

第一:這是危險的想法。如果你把這樣的東西投入生產,要非常小心。可能應該使用鎖或ConcurrentDictionary。

你對一個近似的答案感到滿意嗎?

但是:Reflector顯示count只讀取一些字段並將其返回。這可能不會永遠改變。所以你在這種情況下可以合理地承擔風險。