是否可以在Parallel.For中定义执行顺序?
// parameters.Count == 10
// actualFreeLicenses == 2
Parallel.For(0, parameters.Count, new ParallelOptions()
{
MaxDegreeOfParallelism = actualFreeLicenses
}, i =>
{
ExternalProgram(i);
}
);
当我执行上面的代码时,我注意到传递给 ExternalProgram
方法的 i
的值是 1 & 。 6、稍后2& 7、稍后3& 8 ...
如果我有 14 个参数和 2 个许可证,它总是启动 1 & 8、稍后2& 9 ...
是否可以定义顺序:第一个 1 & 2、稍后3& 4等?
// parameters.Count == 10
// actualFreeLicenses == 2
Parallel.For(0, parameters.Count, new ParallelOptions()
{
MaxDegreeOfParallelism = actualFreeLicenses
}, i =>
{
ExternalProgram(i);
}
);
When I execute the above code I notice that the value of i
passed to the ExternalProgram
method are 1 & 6, later 2 & 7, later 3 & 8 ...
If I have 14 Parameters and 2 licenses it always launch 1 & 8, later 2 & 9 ...
Is it possible to define order: first 1 & 2, later 3 & 4 etc?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在并行循环体中使用 Queue/ConcurrentQueue 并使项目出列怎么样?这将确保保留顺序。
How about using a Queue/ConcurrentQueue and dequeueing items in the body of your parallel loop? This will ensure that ordering is preserved.
如果您使用并行,则它们的执行顺序无关紧要,因此“并行”。如果订单与您相关,您应该使用顺序工作流程。
If you are using Parallel the order in which they are executed is not of relevance therefore "Parallel". You should use a sequential workflow if the order is relevant for you.
听起来您可能想要将
Parallel.ForEach
与自定义分区器 - 但不要忘记它并不是真正执行“1 & 6,然后 2 & 7” - 它正在执行(比如说)1在线程 1 上,在线程 2 上运行 6,然后在线程 2 上运行 7,等等。它不会启动对这样的进程。如果您想启动进程组,您可能应该自己执行分组,然后循环遍历这些组串联,仅提供组内的并行性,通过指定最大并行度等于组大小。
It sounds like you might want to use
Parallel.ForEach
with a custom partitioner instead - but don't forget that it's not really doing "1 & 6, then 2 & 7" - it's doing (say) 1 on thread 1, 6 on thread 2, then 7 on thread 2, etc. It's not launching pairs of processes as such.If you want to launch groups of processes, you should probably perform the grouping yourself, then loop over those groups in series, only providing the parallelism within the group, by specifying a maximum degree of parallelization equal to the group size.
如果您可以改用
ForEach
(在生成一系列数字之后,也许使用IEnumerable.Range
),您可以使用采用分区器
。第三个链接包括一次提供单个元素的示例分区器。If you could switch to using a
ForEach
(after having generated a range of numbers, perhaps, usingIEnumerable.Range
), you could use one of the overloads that takes aPartitioner<T>
. That third link includes a sample partitioner that provides a single element at a time.看起来运行时正在查看您想要使用多少个线程并将工作负载划分为该线程。例如,第一个线程正在处理数据集的前半部分,第二个线程正在处理数据的后半部分。
It would appear that the runtime is looking at how many threads you want to use and dividing the workload up into that. e.g. the first thread is working on the first half of the dataset and the second thread is working on the second half of the data.