Изменено Parallel.ForEach Поведение? - PullRequest
4 голосов
/ 16 февраля 2011

У меня есть класс построения отчетов, который использует параллельную обработку для создания примерно 800 отчетов.

До вчерашнего дня он работал нормально со следующим кодом:

Parallel.ForEach(reports, report => { this.Build(report); });

Примечание: в целях отладки я исключаю код из теста, написанного в тестовом проекте.

Вчера начался сбой. Небольшое копание с помощью Resource Monitor показало, что количество потоков, связанных с qtagent32.exe (исполнителем тестов), постоянно увеличивалось, что в конечном итоге приводило к сбою процесса. Похоже, что-то вдруг стало блокировать.

Мне удалось исправить проблему с небольшим изменением моего кода:

Parallel.ForEach(reports, new ParallelOptions { MaxDegreeOfParallelism = 4 }, report => { this.Build(report); });

Но мне все еще интересно, что изменилось?

1 Ответ

1 голос
/ 16 февраля 2011

Требуется всего 1 элемент, чтобы стать немного медленнее. Если это действительно «тот же код», то есть те же самые отчеты, возможно, это была база данных. Немного больше данных может сделать запрос немного медленнее.

TPL располагается поверх ThreadPool, а ThreadPool будет медленно добавлять новые потоки.

Предположим, что один из ваших отчетов занимает больше времени, чем пороговое значение (500 мс), после чего TP создаст дополнительный поток. Если ваши отчеты конкурируют за что-то (скорее всего, дисковый ввод-вывод), то этот дополнительный поток увеличит вероятность того, что другие отчеты также превысят пороговое значение. С лавиной в результате.

Новый Fx4 Threadpool умнее, чем предыдущий, но все еще грубая эвристика. Ваш MaxDegreeOfParallelism - правильное решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...