繁体   English   中英

在Parallel.Foreach中分块IEnumerable

[英]Chunk partitioning IEnumerable in Parallel.Foreach

有没有人知道让Parallel.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上查看本指南以帮助您入门。

更新:从.NET 4.5开始,他们添加了一个不缓冲数据的Partitioner.Create重载,它具有使自定义分区器的范围最大值为1的相同效果。使用此方法,您将无法获得具有此功能的单个线程一堆排队的工作,如果连续一堆慢的项目运气不好。

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

使用.NET Framework进行并行编程的MSDN 示例包含ChunkPartitioner的实现。 它包含在ParallelExtensionsExtra项目中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM