Делает блок цикла.ForEach, когда больше нет доступных потоков

У нас есть .ForEach цикл (TPL), который запускает много, много, много задач. Поскольку TPL потребляет потоки из пула потоков, мне интересно, что произойдет, если больше нет доступных потоков? Будет ли вызывающий код блокироваться до тех пор, пока потоки снова не станут доступны?

Я знаю, что в пуле потоков есть глобальная рабочая очередь, в которой находятся рабочие элементы (Task) будет поставлен в очередь. Может ли эта очередь быть когда-нибудь полной?

Наша проблема в том, что некоторые задачи выполняются долго (30 минут), а некоторые - короткие (секунда), но у нас есть тысячи таких задач, если не больше. TPL запускает новый поток для каждой задачи, которую я запускаю? Думаю, нет. В какой момент пул потоков будет исчерпан?

1 ответ

Когда свободных потоков больше нет, включается несколько алгоритмов. Главный из них заключается в том, что ThreadPool будет медленно создавать дополнительные потоки (максимум 2 в секунду).

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

Первый подход заключается в указании DegreeOfParallelism для ForEach. Вы хотите ограничить количество потоков до numberOfCores * someFactor где someFactor зависит от ввода-вывода, выполняемого Задачами.

Вы могли бы также исследовать пользовательские планировщики TPL, я не знаю много об этом.

Другие вопросы по тегам