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

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#的目标之一就是让你进入成功的关键:

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)

希望有助于了解正在发生的事情.