gpt4 book ai didi

c# - Parallel.Foreach 中的 block 分区 IEnumerable

转载 作者:IT王子 更新时间:2023-10-29 04:34:48 25 4
gpt4 key购买 nike

有谁知道让 Parallel.Foreach 循环使用 block 分区的方法,我相信默认情况下是范围分区。使用数组时这看起来很简单,因为您只需创建一个自定义分区程序并将负载平衡设置为 true。

由于直到运行时才知道 IEnumerable 中的元素数量,因此我似乎无法找到一种让 block 分区起作用的好方法。

如有任何帮助,我们将不胜感激。

谢谢!

我尝试在每个对象上执行的任务需要花费截然不同的时间来执行。最后我通常要等待几个小时等待最后一个线程完成它的工作。我想要实现的是让并行循环请求分 block 进行,而不是为每个线程预先分配项目。

最佳答案

如果你的 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 答案中涵盖,但您可以查看 this guide on the MSDN让你开始。

更新:从 .NET 4.5 开始,他们添加了一个 Partitioner.Create 不缓冲数据的重载,它与制作范围最大大小为 1 的自定义分区程序具有相同的效果。有了这个,如果它不幸遇到一堆,你将不会得到一个有一堆排队工作的线程连续缓慢的项目。

var partitoner = Partitioner.Create(source, EnumerablePartitionerOptions.NoBuffering);
Parallel.ForEach(partitoner, item =>
{
//Do work
}

关于c# - Parallel.Foreach 中的 block 分区 IEnumerable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16427214/

25 4 0