Делает блок цикла .ForEach, когда больше нет доступных потоков - PullRequest
2 голосов
/ 11 октября 2011

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

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

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

1 Ответ

4 голосов
/ 11 октября 2011

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

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

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

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

...