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不是线程安全的。在你自己的线程安全包装器上实现它。