C#中的并发集合
时间:2020-03-05 18:46:13 来源:igfitidea点击:
我正在寻找一种在Cor中获取并发集合的方法,至少是一个支持并发枚举器的集合。现在,当我要遍历的集合发生更改时,我将收到InvalidOperationException。我可以深度复制收藏集并使用私有副本,但是我想知道是否有更好的方法
程式码片段:
foreach (String s in (List<String> )callingForm.Invoke(callingForm.delegateGetKillStrings)) { //do some jazz }
- 编辑 -
我得到了答案,但是还发现我需要确保正在写入集合的代码也需要尝试获得锁定。
private void addKillString(String s) { lock (killStrings) { killStrings.Add(s); } }
解决方案
回答
除了进行深度复制以外,最好的选择是锁定集合:
List<string> theList = (List<String> )callingForm.Invoke(callingForm.delegateGetKillStrings); lock(theList.SyncRoot) { foreach(string s in theList) { // Do some Jazz } }
回答
因此,我不太确定我们要问的是什么,但是Parallel Extensions团队已经整理了一些符合要求的内容。特别是请参阅此博客文章,有关枚举并行集合。它还包含一个下载Parallel CTP的链接,我们当然可以浏览其余的博客文章,以了解CTP的用途以及编程模型的工作原理。
回答
如果要使用FCL集合,则锁定是支持可能重叠的多个线程进行迭代/修改的唯一方法。
但是,请小心用作锁定对象的内容。仅当集合本身是使用它的类的私有成员时,才使用SyncRoot。如果该集合是受保护的或者公共的,则类的客户端可以在SyncRoot上获得自己的锁,从而可能与类中的代码死锁。
如果我们有兴趣了解第三方收藏库,我建议我们使用出色的C5通用收藏库。他们有一个基于树的集合家族,可以在不锁定的情况下轻松,安全地同时对其进行修改和迭代,有关详细信息,请参见其(优秀)文档的8.10和9.11节。