D.R*_*.R. 9 .net c# parallel.foreach
是Parallel.ForEach()有MaxDegreeOfParallelism==1保证的处理输入的顺序枚举?
如果答案是"否",是否有办法强制执行此行为?
joh*_*ose 13
首先,微软关于并行编程的官方文档说明执行顺序无法保证是正确的.
Parallel.ForEach方法不保证执行顺序.与顺序ForEach循环不同,传入值并不总是按顺序处理.
最好在Parallel.ForEach设计公共API时使用:以并行方式处理项目.如果您需要按顺序处理项目,那么使用常规foreach循环会更好.意图比使用更清晰MaxDegreeOfParallelism = 1.
话虽如此,出于好奇,我看了一下.NET 4.7.1的源代码.简短的回答是肯定的,如果是,项目将按顺序处理MaxDegreeOfParallelism = 1.但是,您不应该依赖于此以用于将来的实现,因为它可能并不总是这样.
考虑看看Parallel.ForEach,并通过它之后,你最终会看到,对集合进行遍历被分区(这个过程略有不同它是否是一个TSource[],List<TSource>或者一个IEnumerable<TSource>.
Task.SavedStateForNextReplica并且Task.SavedStateFromPreviousReplica被覆盖ParallelForReplicaTask以便在并行运行的任务之间传递状态.在这种情况下,它们用于通信任务应迭代的分区.
最后,让我们来看看Task.ExecuteSelfReplicating.基于指定的并行度以及任务调度程序的ParallelForReplicatingTask覆盖.因此,这只会创建一个子任务.因此,此任务仅在创建的单个分区上运行.ShouldReplicateMaximumConcurrencyLevelMaxDegreeOfParallelism = 1
因此,要回答你的问题:写作的,Parallel.ForEach有MaxDegreeOfParallism = 1将枚举集从开始到结束的TSource[],从开始到结束的一个IList<TSource>,并且使用GetEnumerator一个IEnumerable<TSource>,与依靠,如果稍有不同的路径IEnumerable<TSource>可以被强制转换为OrderablePartitioner<TSource>或不.这三条路径是在确定的Parallel.ForEachWorker.
我强烈建议您自己浏览源代码以便自己查看.
我希望能够回答你的问题,但要记住这一点非常重要:不要依赖于此.这种实现很可能在将来发生变化.