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节。