Подтвердить что ты не робот

Разбиение пакетов IEnumerable в Parallel.Foreach

Кто-нибудь знает, как получить цикл Parallel.Foreach для использования секционирования chunk в сравнении с тем, что, по моему мнению, является разделом по умолчанию по умолчанию. Это кажется простым при работе с массивами, потому что вы можете просто создать пользовательский разделитель и установить балансировку нагрузки на true.

Так как количество элементов в IEnumerable неизвестно до выполнения, я не могу понять, как можно эффективно работать с секцией chunk.

Любая помощь будет оценена.

спасибо!

Задачи, которые я пытаюсь выполнить для каждого объекта, выполняются в разное время. В конце я обычно жду часа, пока последний поток не завершит свою работу. То, что я пытаюсь достичь, состоит в том, чтобы параллельный цикл запроса обрабатывался вдоль пути вместо предварительного выделения элементов в каждый поток.

4b9b3361

Ответ 1

Если ваш 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
}