Parallel.ForEach 会按 MaxDegreeOfParallelism=1 的顺序进行处理吗?

2023-12-31

Is Parallel.ForEach() with MaxDegreeOfParallelism==1保证按顺序处理可枚举的输入?

如果答案是“否”,有没有办法强制执行这种行为?


首先,以下说法正确的是微软关于并行编程的官方文档 https://msdn.microsoft.com/library/ff963552.aspx指出不保证执行顺序.

Parallel.ForEach 方法不保证执行顺序。与顺序 ForEach 循环不同,传入值并不总是按顺序处理。

最好使用Parallel.ForEach公共 API 的设计如下:以并行方式处理项目。如果您需要按顺序处理项目,那么最好使用常规方法foreach环形。意图比使用更明确MaxDegreeOfParallelism = 1.

话虽如此,出于好奇,我查看了 .NET 4.7.1 的源代码。简短的答案是是的,如果出现以下情况,将按顺序处理这些项目MaxDegreeOfParallelism = 1。但是,您不应该在未来的实现中依赖于此,因为它可能并不总是这样。

  1. 看看Parallel.ForEach https://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Parallel.cs,d64f86dd50921f5b继续下去,您最终会看到要迭代的集合已分区(无论它是一个集合,这个过程都略有不同)TSource[], List<TSource>, or an IEnumerable<TSource>.

  2. Task.SavedStateForNextReplica and Task.SavedStateFromPreviousReplica被覆盖在ParallelForReplicaTask为了在并行运行的任务之间传达状态。在这种情况下,它们用于传达任务应该迭代的分区。

  3. 最后我们来看看Task.ExecuteSelfReplicating https://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Task.cs,b10f1afbb0308278. ParallelForReplicatingTask覆盖ShouldReplicate基于指定的并行度以及任务调度程序的MaximumConcurrencyLevel。所以,这与MaxDegreeOfParallelism = 1只会创建一个子任务。因此,此任务将仅对创建的单个分区进行操作。

所以,回答你的问题:截至撰写本文时,Parallel.ForEach with MaxDegreeOfParallism = 1将枚举集合从开始到结束 https://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Parallel.cs,6cd8a40307748c3d for a TSource[], 从开始到结束 https://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Parallel.cs,9e0ecf73a270a93a for an IList<TSource>, and use GetEnumerator https://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Parallel.cs,38a83efeaf70c495 for an IEnumerable<TSource>,路径略有不同,具体取决于是否IEnumerable<TSource>可以转换为OrderablePartitioner<TSource>或不。这三个路径由Parallel.ForEachWorker https://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Parallel.cs,ecf3d8a35545d82b.

我强烈建议您自行浏览源代码以亲自查看。

我希望这能够回答您的问题,但记住这一点非常重要:不要依赖这个。这种实现方式很可能在未来发生改变。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Parallel.ForEach 会按 MaxDegreeOfParallelism=1 的顺序进行处理吗? 的相关文章

随机推荐