Parallel.ForEach Ordered Execution

Jef*_*f Z 18 parallel-processing foreach html-lists c#-4.0

我试图使用新的C#4.0 Parallel.ForEach函数在对象列表上执行并行函数.这是一个非常漫长的维护过程.我想让它按列表的顺序执行,以便我可以在前一点停止并继续执行.我该怎么做呢?

这是一个例子.我有一个对象列表:a1 to a100.这是当前的订单:

a1, a51, a2, a52, a3, a53...
Run Code Online (Sandbox Code Playgroud)

我想要这个订单:

a1, a2, a3, a4...
Run Code Online (Sandbox Code Playgroud)

我可以将一些对象无序运行,但只要我能在列表中找到一个点,我可以说在此之前所有对象都已运行.我阅读了并行编程csharp白皮书,但没有看到任何相关内容.ParallelOptions课堂上没有这个设置.

小智 6

做这样的事情:

int current = 0;
object lockCurrent = new object();

Parallel.For(0, list.Count, 
             new ParallelOptions { MaxDegreeOfParallelism = MaxThreads },
             (ii, loopState) => {
                    // So the way Parallel.For works is that it chunks the task list up with each thread getting a chunk to work on...
                    // e.g. [1-1,000], [1,001- 2,000], [2,001-3,000] etc...
                    // We have prioritized our job queue such that more important tasks come first. So we don't want the task list to be
                    // broken up, we want the task list to be run in roughly the same order we started with. So we ignore tha past in 
                    // loop variable and just increment our own counter.
                    int thisCurrent = 0;
                    lock (lockCurrent) {
                        thisCurrent = current;
                        current++;
                    }
                    dothework(list[thisCurrent]);
                 });
Run Code Online (Sandbox Code Playgroud)

您可以看到,当您跳出并行 for 循环时,您将知道要执行的最后一个列表项(假设您让所有线程在中断之前完成)。我不太喜欢 PLINQ 或 LINQ。老实说,我不明白编写 LINQ/PLINQ 如何带来可维护的源代码或可读性...... Parallel.For 是一个更好的解决方案。


Chr*_*lor 1

作为替代建议,您可以记录已运行的对象,然后在恢复执行时过滤列表以排除已运行的对象。

如果这需要在应用程序重新启动时保持不变,您可以存储已执行的对象的 ID(我假设这里的对象有一些唯一的标识符)。