2012-06-27 49 views
14

就线程安全而言,这可以做或我需要使用不同的集合吗?Parallel.ForEach上市<Object>线程安全

 List<FileMemberEntity> fileInfo = getList(); 

     Parallel.ForEach(fileInfo, fileMember => 
     { 
       //Modify each fileMember 
     } 
+0

请保持问题奇异。 – 2012-06-27 17:53:04

+1

你在修改foreach循环中的任何内容吗?如果不是,那么可能不需要考虑线程安全性。如果您正在修改,那么您需要执行锁定 – Didaxis

+0

我可以使用不同的集合并且不需要锁定 –

回答

22

只要您只修改传递给该方法的项目内容,就不需要锁定。

(当然前提是有列表中没有重复的参考,即两个引用相同FileMemberEntity实例。)

如果您需要修改列表本身,创建一个副本,你可以迭代和修改列表时使用锁:

List<FileMemberEntity> fileInfo = getList(); 

List<FileMemberEntity> copy = new List<FileMemberEntity>(fileInfo); 
object sync = new Object(); 

Parallel.ForEach(copy, fileMember => { 
    // do something 
    lock (sync) { 
    // here you can add or remove items from the fileInfo list 
    } 
    // do something 
}); 
+0

正在收集的内容....收集中包含的内容是否正确? –

+0

@MicahArmantrout:作为'fileMember'传递给方法的'FileMemberEntity'实例中的内容。 – Guffa

+0

那么这将使所有其他线程停止,直到它离开锁或与Parallel.ForEach将线程继续到列表中的另一个项目? –

4

你很安全,因为你只是在阅读。在迭代其项目时​​,不要修改列表。

+0

我正在修改集合中的项目 –

+0

这很好,只要因为你没有修改实际的集合本身。您无法对其中的项目重新排序,也无法向其添加或删除项目。 – Henrik

+1

因此,如果我正在更新列表中的项目,只要最后我不更改实际的集合,这并不重要? –

1

如果FileMemberEntity对象执行的操作顺序无关紧要,则可以使用List<T>,因为您没有修改该列表。

如果您必须确保某种排序,则可以使用OrderablePartitioner<T>作为基类并实施适当的分区方案。例如,如果FileMemberEntity有某种分类,并且您必须按某种特定顺序处理每个类别,则您需要转到该路线。

可以想像,如果你有

对象1 A类

对象2 A类

对象3 B类

没有保证Object 2 Category A将前被处理使用迭代List<T>时处理。

您链接到的MSDN文档提供了一个如何执行此操作的示例。

+0

我在修改foreach中的集合 –

+0

如果您要修改集合中的对象(而不是集合本身),那就好了。 –

+0

非常感谢! –

2

我们应该使用更少的锁对象来使其更快。只有在Parrallel.ForEach不同的本地线程锁对象:

List<FileMemberEntity> copy = new List<FileMemberEntity>(fileInfo); 
object sync = new Object(); 

Parallel.ForEach<FileMemberEntity, List<FileMemberEntity>>(
     copy, 
    () => { return new List<FileMemberEntity>(); }, 
     (itemInCopy, state, localList) => 
     { 
     // here you can add or remove items from the fileInfo list 
     localList.Add(itemInCopy); 
     return localList; 
     }, 
     (finalResult) => { lock (sync) copy.AddRange(finalResult); } 
); 

// do something 

参考:http://msdn.microsoft.com/en-gb/library/ff963547.aspx