块分区在Parallel.Foreach中可枚举
本文关键字:枚举 Foreach Parallel 分区 | 更新日期: 2023-09-27 18:12:26
有没有人知道如何获得平行?Foreach循环使用块分区,而不是默认的范围分区。在处理数组时,这似乎很简单,因为您只需创建一个自定义分区并将负载平衡设置为true。
由于IEnumerable中的元素数量直到运行时才知道,我似乎找不到一个好方法来获得块分区的工作。
如有任何帮助,不胜感激。
谢谢!
我试图在每个对象上执行的任务需要明显不同的时间来执行。最后,我通常要等上几个小时,等待最后一个线程完成它的工作。我想要实现的是在并行循环请求块的过程中,而不是预先分配项目到每个线程。
如果你的IEnumerable真的有一个索引器(即你可以使用obj[1]
来获取一个项目)你可以做以下操作
var rangePartitioner = Partitioner.Create(0, source.Length);
Parallel.ForEach(rangePartitioner, (range, loopState) =>
{
// Loop over each range element without a delegate invocation.
for (int i = range.Item1; i < range.Item2; i++)
{
var item = source[i]
//Do work on item
}
});
但是,如果它不能这样做,您必须通过创建从System.Collections.Concurrent.Partitioner<TSource>
派生的新类来编写自定义分区器。这个主题太宽泛了,不能在SO的答案中涵盖,但是你可以看看MSDN上的这个指南来开始。
UPDATE:在。net 4.5中,他们添加了一个Partitioner.Create
过载,它不缓冲数据,它具有与创建一个范围最大大小为1的自定义分区相同的效果。有了这个,你就不会得到一个线程,有一堆排队的工作,如果它不幸与一堆慢的项目在一行。
var partitoner = Partitioner.Create(source, EnumerablePartitionerOptions.NoBuffering);
Parallel.ForEach(partitoner, item =>
{
//Do work
}