gpt4 book ai didi

c# - TaskFactory.Tasks 中 BlockingCollection.GetConsumingEnumerable() 集合的 Parallel.ForEach 和 foreach 循环

转载 作者:行者123 更新时间:2023-11-30 13:12:28 33 4
gpt4 key购买 nike

我已经对这两个循环进行了试验,并开始注意到,即使任务的 Action 委托(delegate)中的常规 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);
}
});

代码 2:

Task loadingTask2 = Factory.StartNew(() =>
{
Parallel.ForEach(Queue.GetConsumingEnumerable(), (dg) =>
{

MyOtherClass vl = new MyOtherClass();
vl.Id = dg.Id;
vl.PerformTimeConsumingAction();

OutputQueue.Add(vl);
});
});

代码 1 使用 Console.Write 语句运行时,每次迭代似乎都在等待前一个循环完成,直到它获取下一个循环,但代码 2 确实并行处理多个元素。

我是否没有正确理解 Task.Action 中的常规 foreach?我认为 .NET 会根据负载保证为任务启动尽可能多的线程,并且 foreach 的每次迭代都会并行处理。

我还尝试将 PLINQ 结果传递给上述代码和观察者相同的行为:常规 foreach 似乎等待上一次迭代完成以启动下一次迭代,即使我使用了 .AsParallel() .WithExecutionMode(ParallelExecutionMode.ForceParallelism) 指令。

任何见解将不胜感激。我知道 OrderingPartitioner 类并可以尝试使用它

最佳答案

常规的 foreach 总是 按顺序运行它的迭代。在某些情况下,没有什么魔法可以将其变成并行结构。那就像把你扔进pit of despair ,因为这样就很难断言像 foreach 循环这样简单的东西的正确性。幸运的是,C# 的目标之一就是把你扔进成功的坑里:

C# throwing you into the pit of success

如果您将一个 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

Parallel.Foreach 的执行流程如下所示:

                  |
_________________v________________
/ / / / \ \ \ \
|1 |2 |3 |....| |n-2 |n-1 |n
\____\____\____\____/____/____/____/
|
v

希望这有助于理解正在发生的事情。

关于c# - TaskFactory.Tasks 中 BlockingCollection.GetConsumingEnumerable() 集合的 Parallel.ForEach 和 foreach 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5694622/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com