题
我正在寻找一种在 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 节。
不隶属于 StackOverflow