我正在寻找一种在 C# 中获取并发集合的方法,或者至少是一个支持并发枚举器的集合。现在,当我正在迭代的集合发生更改时,我收到 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
        }
    }

其他提示

所以我不太确定你在问什么,但并行扩展团队已经整理了一些可能符合要求的东西。特别请参阅这篇博文,关于 枚举并行集合. 。它还包含下载并行 CTP 的链接,您当然可以浏览博客文章的其余部分,以了解 CTP 的用途以及编程模型的工作原理。

如果您想使用 FCL 集合,那么锁定是支持可能重叠的多个线程迭代/修改的唯一方法。

不过,要小心用作锁定对象的内容。仅当集合本身是使用它的类的私有成员时,使用 SyncRoot 才是一个好主意。如果该集合是受保护的或公共的,那么您的类的客户端可以在您的 SyncRoot 上获取自己的锁定,这可能会与您的类中的代码发生死锁。

如果您有兴趣查看第 3 方集合库,我推荐优秀的 C5通用集合库. 。他们有一系列基于树的集合,可以轻松、安全地同时修改和迭代,而无需锁定 - 有关详细信息,请参阅其(优秀)文档的第 8.10 和 9.11 节。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top