1

我有一個ObservableCollection<T>在我的項目之一,我需要使訪問線程安全。
特別是,我需要一個線程安全的枚舉器。這意味着,在迭代集合期間(例如,在LINQ查詢期間),沒有人應該能夠添加項目。線程安全替換ObservableCollection <T>在C#4.0中,安全枚舉

我注意到了.NET 4.0命名空間中的類System.Collections.Concurrent。然而他們中沒有一個似乎匹配。另外,在MSDN doc,我沒有找到一個關於哪個訪問實際上線程安全的段落。

是否存在某個現有的線程安全集合,我可以使用它,還是必須自己實現?

+1

*(例如在LINQ查詢)遍歷集合時,沒有人應該能夠添加一個項目。*如果有人試圖當你迭代它項添加到收藏應該發生什麼?它應該拋出異常嗎?塊?成功但不會在迭代中出現? – 2010-11-10 13:32:51

+0

@馬克,謝謝你的想法。我想阻止更新。 – Marcel 2010-11-10 13:34:19

+0

請嘗試以下鏈接提供了一個線程安全的解決方案,從任何線程工作,並且可以通過多種UI線程綁定到:http://www.codeproject.com/Articles/64936/Multithreaded-ObservableImmutableCollection – Anthony 2014-04-15 19:19:40

回答

5

記住,如果你把一個鎖在GetEnumerator方法,你可能會持有很長一段時間的鎖定,在此期間,沒有人能夠將對象添加到您的收藏:

foreach (var o in myCollection) { 
    // Do something that takes 10 minutes 
} 

您還需要考慮如果多次迭代同時發生會發生什麼。這意味着某種MRSW鎖(多讀卡器單個寫入器),您可能必須自己實施。

這聽起來像你真正需要做的是遍歷集合的快照:

foreach (var o in myCollection.ToArray()) { 
    // ... 
} 

要正確地做到這一點,你需要實現自己的ICollection<T>是取出鎖在ToArrayAdd方法

如果您更精確地給出您的要求或規範,它可能會有所幫助。

+0

感謝,thecoop,爲那個啓發性的答案。我現在在從收集閱讀使用一個簡單的鎖()'編調用。這是一個相對較短的電話,我可以忍受其他人被阻止的事實。很高興知道您提到的選項! – Marcel 2010-11-12 07:42:23

0

ObservableCollection不是線程安全的。在你自己的線程安全包裝器上實現它。