2012-11-13 2 views
1

У меня есть сценарий, в котором я должен запустить вложенный foreach для создания списка. Псевдо-код, что я делаю нижеParallel.ForEach производит неточный вывод

foreach(var x in list)   (ForEach1) 
    get m // List<string> 
    foreach(var k in m)   (ForEach2) 
    get t // List<string> 
     foreach(var o in t)  (ForEach3) 
      // Do some work. and add output to a list 
      // which is defined before first for each 

Однако, поскольку я извлечения данных из внешней системы (от Perforce, запустив Perforce команды) в Foreach2 и Foreach3, этот кусок кода работает очень медленно, и мне нужно чтобы ускорить это.

Я попытался использовать Parallel.ForEach для запуска ForEach1 или ForEach2 параллельно. В моих тестах это значительно улучшило производительность, но привело к неточному результату.

  • Если я запускаю этот код с заявлениями Foreach, список производит содержит 625 пунктов (что верно)
  • Если я использую Parallel.ForEach для ForEach1, я получаю 325 добавлен в список, который значительно ниже чем я ожидаю.
  • И, наконец, если я использую Parallel.ForEach для ForEach2, я получаю 605 элементов, добавленных в список, еще 20 пропавших без вести.

Я не уверен, что я делаю неправильно, или то, что мне не хватает. какие вещи нужно учитывать при использовании Parallel foreach или для?

Может ли кто-нибудь помочь мне разобраться, пожалуйста? любое другое предложение, чтобы повысить производительность был бы оценен

Благодаря

+1

Это может иметь некоторую помощь http://stackoverflow.com/questions/13142099/making-the-most-of-the-net-task-parallel-library – series0ne

+0

Вы пробовали использовать параллельно версия для ForEach3? – fofik

+0

Звучит как состояние гонки. Коллекция, которую вы добавляете для окончательных результатов, представляет собой поточно-безопасную коллекцию (например, ConcurrentBag )? – flipchart

ответ

1

Я не знаю, что ваша «получить» операцию, но она также может быть проблемой с закрытием. Вы можете искать в сети. Например The foreach identifier and closures и http://www.codethinked.com/c-closures-explained

+0

Возможно, это так. Пример того, как исправить, будет хорошим. Например, вместо 'get t; foreach (var o in t) ', напишите' get t; var t_copy = t; foreach (var o in t_copy) ' –

Смежные вопросы