Parallel.Foreach поддерживать порядок сбора? - PullRequest
3 голосов
/ 09 ноября 2010

Есть ли способ гарантировать заказ при использовании Parallel.ForEach()?Коллекция, над которой я работаю, должна поддерживать порядок, но я искал улучшения производительности.

Ответы [ 4 ]

6 голосов
/ 30 марта 2011

Итак, у вас есть утверждение, которое выглядит примерно так? (основываясь на ваших комментариях выше).

Parallel.Foreach(myData, ..., (d) =>
{
  StringBuilder sb = new StringBuilder();
  sb.Append(d);
  // WriteLine sb?
});

У этого подхода есть ряд проблем.

  1. Ни Parallel.For, ни Parallel.ForEach не гарантируют, что ваш доступ к содержимому myData будет доступен в любом конкретном порядке.
  2. если вы используете метод на консоли или общий StringBuilder либо вывести результаты, либо создать полную строку, то вы вероятно блокируют общий ресурс, эффективно сериализуя части вашего параллельного цикла.

Трудно сказать больше, не видя конкретного примера вашего кода. В зависимости от того, что вы делаете, вы можете использовать сохранение порядка AsOrdered() в PLINQ, чтобы получить то, что вам нужно.
См. этот ресурс MSDN и Заказано PLINQ ForAll

Это позволит вам вернуть упорядоченный набор результатов на основе порядка ввода, но не гарантирует порядок фактической обработки. Однако если параллельный запрос блокирует вызов в теле, вы вряд ли получите хорошую производительность.

3 голосов
/ 26 апреля 2018

Чтобы сохранить порядок, вы должны попытаться упорядочить список перед передачей его в цикл foreach, поскольку по умолчанию Parallel.Foreach обрабатывает список как неупорядоченный.

Пример:

Parallel.ForEach(
list.AsParallel().AsOrdered(), 
(listItems) => {<operations that you need to do>});
0 голосов
/ 05 января 2014

Для тех, кто ищет простое решение, я опубликовал 2 метода расширения (один с использованием PLINQ и один с использованием Parallel.ForEach) как часть ответа на следующий вопрос:

Заказано PLINQ ForAll

0 голосов
/ 09 ноября 2010

нет, ForEach должен использоваться только для условий, где порядок не имеет значения;попробуйте Parallel.For

...