Dim*_*tri 3 c# parallel-processing multithreading task-parallel-library
我已经尝试了这两个循环,并注意到即使Task的Action委托中的常规foreach循环应该并行执行,它也不会并行处理元素.但是,如果我用Parallel.ForEach替换它,我看到数据正在跨多个线程并行处理.
代码1:
Task loadingTask1 = Factory.StartNew(() =>
{
foreach (MyOneClass dg in Queue.GetConsumingEnumerable())
{
MyOtherClass vl = new MyOtherClass();
vl.Id = dg.Id;
vl.PerformTimeConsumingAction();
OutputQueue.Add(vl);
}
});
Run Code Online (Sandbox Code Playgroud)
代码2:
Task loadingTask2 = Factory.StartNew(() =>
{
Parallel.ForEach(Queue.GetConsumingEnumerable(), (dg) =>
{
MyOtherClass vl = new MyOtherClass();
vl.Id = dg.Id;
vl.PerformTimeConsumingAction();
OutputQueue.Add(vl);
});
});
Run Code Online (Sandbox Code Playgroud)
在每次迭代时使用Console.Write语句运行的代码1似乎等待上一个循环完成,直到它抓住下一个循环,但代码2确实并行处理多个元素.
我是否正确理解Task.Action中的常规foreach?我认为.NET将启动尽可能多的任务线程作为加载保证,并且每个迭代的foreach将被并行处理.
我也尝试将PLINQ结果传递给上述代码和观察者相同的行为:常规foreach似乎等待上一次迭代完成以启动下一个代码,即使我已经使用了.AsParallel()
和.WithExecutionMode(ParallelExecutionMode.ForceParallelism)
指令.
任何见解都将受到高度赞赏.我知道OrderingPartitioner类,可能会尝试使用它
R. *_*des 18
常规foreach 始终按顺序运行迭代.在某些情况下,没有魔法可以将它变成并行构造.这就像把你扔进了绝望的陷阱,因为那样就很难断言像foreach循环一样简单的东西的正确性.幸运的是,C#的目标之一就是让你进入成功的关键:
如果将foreach循环运行在单独的任务上,则会使所有迭代按顺序运行,但您可以与整个foreach并行运行其他代码.
在单独的任务上执行常规foreach的流程如下所示:
|
__v_
/ \
other code | | foreach iteration 1
other code | | foreach iteration 2
other code | | foreach iteration 3
......
other code | | foreach iteration n-1
other code | | foreach iteration n
v v
Run Code Online (Sandbox Code Playgroud)
并且执行的流程Parallel.Foreach
看起来像这样:
|
_________________v________________
/ / / / \ \ \ \
|1 |2 |3 |....| |n-2 |n-1 |n
\____\____\____\____/____/____/____/
|
v
Run Code Online (Sandbox Code Playgroud)
希望有助于了解正在发生的事情.