Отслеживайте прогресс при использовании Parallel.ForEach - PullRequest
11 голосов
/ 06 октября 2010

Я рефакторинг моей программы для использования Parallel.ForEach.Раньше, когда я использовал обычный цикл for, я обновлял индикатор выполнения WPF с помощью Dispatcher, отображая% выполненных операций путем деления текущего индекса массива на размер массива.В параллельном цикле foreach это не отображается должным образом, т. Е.% Скачкообразно, что ожидается.

Как я могу обновить индикатор выполнения WPF с параллели для каждого цикла, чтобы я мог отслеживать количество выполненных итераций?

Ответы [ 2 ]

9 голосов
/ 06 октября 2010

Как предполагает SLaks, вы должны просто увеличить значение индикатора выполнения вместо того, чтобы устанавливать его в соответствии с текущим индексом, полученным с помощью метода Parallel.For.

Однако я бы серьезно подумал об использовании более дешевого способа, чем отправка сообщения в поток пользовательского интерфейса при каждой итерации. Если у вас большое количество итераций, отправка сообщения с каждой итерацией может быть довольно сложной. Вы можете объявить локальную переменную count и использовать Interlocked.Increment для безопасного увеличения переменной в теле параллельного цикла.

  • Тогда вы можете использовать что-то вроде if (count % 10 == 0) // ..., чтобы обновлять графический интерфейс только после 10 итераций. (Это не совсем правильно, так как другие потоки могут обновлять count перед проверкой, но если это только для целей уведомления GUI, то это не должно иметь значения - вы определенно не хотите использовать lock в теле цикла).

  • Кроме того, вы можете создать таймер, который будет неоднократно проверять значение count из потока графического интерфейса и обновлять индикатор выполнения. Возможно, это еще проще, и вы можете гарантировать, что индикатор выполнения будет обновляться достаточно часто, но не более.

4 голосов
/ 06 октября 2010

Каждый раз, когда вы завершаете операцию, вы должны публиковать сообщение в ветке пользовательского интерфейса (вызывая Dispatcher.BeginInvoke, который увеличивает индикатор выполнения на 1.

...