0

我有一個使用ConcurrentDictionary的類。3線程使用的C#ConcurrentDictionary

在這個類中,有三個函數在這個ConcurrentDictionnary上執行一些操作。

每個函數都由不同的線程調用。

  • 第一功能操作:dictionnary.Where,dictionnary.TryRemove
  • 二級功能操作:dictionnary.Where
  • 第三個功能操作:dictionnary.TryAdd

while (!dictionnaryKey.TryAdd(key, item)) 
{ 
    LogWriter.error_log("try add to dictionnary ..."); 
} 

這最後的功能塊在不同的時間。我必須將我的元素添加到字典中而不會阻塞,但我該怎麼辦?

+2

爲什麼要添加一個沒有阻塞的元素?這並不能阻止阻塞收集的全部目的,並且最終會失去線程安全性。你可以使用一個正常的字典。 – Maarten 2014-10-17 09:17:03

+0

帶鎖的普通字典的性能會低於併發字典。你如何測量阻塞?你同時運行多少個線程? – 2014-10-17 09:22:33

+0

這樣做的一個選擇是有一個額外的線程負責添加和刪除,另外兩個字典是一個用於添加和另一個用於刪除的字典。如果您想在任何線程中添加某些內容,請將其添加到添加堆棧(與刪除相同)。在額外的線程中,如果任何一個堆棧中有某些東西並且隨意執行該操作,則以1秒爲間隔(或其他)檢查,首先從添加堆棧中添加所有內容,然後從刪除堆棧中刪除全部。 – Vajura 2014-10-17 09:26:14

回答

1
I have to add my element to the dictionary without blocking, but how can I do? 

這是不可能的。 ConcurrentDictionary針對多線程和低爭用進行了優化,但這並不意味着沒有爭用(阻塞)。 ConcurrentDictionary中的所有寫入操作都使用精細鎖定模型,並且內部使用多個鎖定對象來同步寫入操作,以保持數據一致並防止出現多線程異常。

您的TryAdd方法明顯被阻塞,因爲它正在等待鎖定(由其他線程獲取)才能獲得釋放。

併發字典枚舉(例如您的Where操作)未被阻止的原因是因爲它們使用了無鎖型號的型號。

使用普通舊字典而不是ConcurrentDictionary不會產生任何性能優勢,因爲您必須使用讀寫鎖自己處理鎖定。

由於@Usr在你的評論說,如果你的目標是有無阻塞處理比你的全在你的多作家使用單一ConcurrentDictionary情況可能是錯誤的概念。