Я экспериментировал с обоими этими циклами и заметил, что хотя обычный цикл foreach в делегате Action Task должен работать параллельно, он не обрабатывает элементы параллельно. Однако, если я заменю его на Parallel.ForEach, я увижу, что данные обрабатываются параллельно в нескольких потоках.
Код 1:
Task loadingTask1 = Factory.StartNew(() =>
{
foreach (MyOneClass dg in Queue.GetConsumingEnumerable())
{
MyOtherClass vl = new MyOtherClass();
vl.Id = dg.Id;
vl.PerformTimeConsumingAction();
OutputQueue.Add(vl);
}
});
Код 2:
Task loadingTask2 = Factory.StartNew(() =>
{
Parallel.ForEach(Queue.GetConsumingEnumerable(), (dg) =>
{
MyOtherClass vl = new MyOtherClass();
vl.Id = dg.Id;
vl.PerformTimeConsumingAction();
OutputQueue.Add(vl);
});
});
Код 1 при запуске с оператором Console.Write на каждой итерации, кажется, ожидает завершения предыдущего цикла, пока не перехватит следующий, но Код 2 обрабатывает несколько элементов параллельно.
Не правильно ли я понимаю обычный foreach в Task.Action? Я думал, что .NET запустит столько задач для задачи, сколько и нагрузки, и каждая итерация foreach будет обрабатываться параллельно.
Я также пытался передать результат PLINQ обоим вышеприведенным кодам и тому же поведению наблюдателя: обычный foreach, казалось, ожидал завершения предыдущей итерации, чтобы начать следующую, хотя я использовал .AsParallel()
и .WithExecutionMode(ParallelExecutionMode.ForceParallelism)
директивы.
Любое понимание будет высоко оценено.
Мне известен класс OrderingPartitioner, и я могу попробовать использовать его