2008-09-02 65 views
3

我正在寻找一种在C#中获取并发集合或至少支持并发枚举器的集合的方法。现在,当我迭代的集合发生变化时,我得到一个InvalidOperationException异常。我可能只是深拷贝的收集和使用私人拷贝工作,但我不知道是否有可能是一个更好的办法C#中的并发集合

代码片段:

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

- 编辑 -

我把答案还发现我需要确保写入集合的代码也需要尝试锁定。

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

回答

5

除了做深复制你最好的选择可能是锁定集合:

List<string> theList = (List<String>)callingForm.Invoke(callingForm.delegateGetKillStrings); 
    lock(theList.SyncRoot) { 
     foreach(string s in theList) { 
       // Do some Jazz 
     } 
    } 
4

所以我不太清楚你问什么,但并行扩展团队把一些可能符合法案的东西放在一起。特别是关于enumerating parallel collections的博客文章。它还包含下载并行CTP的链接,您当然可以浏览其他博客文章,以了解CTP的意图和编程模型的工作原理。

1

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

不过要小心你用作锁对象。如果集合本身是使用它的类的私有成员,则使用SyncRoot只是一个好主意。如果集合受保护或公开,那么您的类的客户端可能会在SyncRoot上占用自己的锁,这可能会导致类中的代码发生死锁。

如果您有兴趣查看第三方收藏图书馆,我推荐优秀的C5 Generic Collection Library。他们拥有一系列基于树的集合,可以轻松安全地修改和重复同时进行迭代,而无需锁定 - 有关详细信息,请参阅其优秀文档的第8.10和第9.11节。