3

我正在寻找一种在C#中获取并发集合的方法,或者至少是一个支持并发 enumerator的集合。现在,我正在迭代的集合发生变化。 InvalidOperationException

我可以深度复制收藏并使用私人副本,但我想知道是否有更好的方法

代码片段:

foreach (String s in (List<String>) callingForm.Invoke(callingForm.delegateGetKillStrings))
{
    //do some jazz
}

- 编辑 -

我接受了答案,但也发现我需要确保写入集合的代码也需要尝试获取锁。

private void addKillString(String s)
{
    lock (killStrings)
    {
        killStrings.Add(s);
    }
}
4

3 回答 3

5

除了进行深度复制之外,您最好的选择可能是锁定集合:

   List<string> theList = (List<String> )callingForm.Invoke(callingForm.delegateGetKillStrings);
    lock(theList.SyncRoot) {
        foreach(string s in theList) {
               // Do some Jazz
        }
    }
于 2008-09-02T03:25:49.087 回答
4

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

于 2008-09-02T03:27:42.810 回答
1

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

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

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

于 2008-09-02T14:30:01.827 回答