Вопрос о потоках — Что произойдет, если в пуле потоков не будет доступных потоков?

#c# #multithreading

#c# #многопоточность

Вопрос:

У меня есть следующий код:

 CancellationTokenSource cancelSource = new CancellationTokenSource();
_cancelTokenList.Add(cancelSource);

CancellationToken token = cancelSource.Token;

Task.Factory.StartNew(() =>
{
   StartTest(token);
}, token);
  

Будет ли выдано исключение, если нет доступных потоков для обслуживания запроса на новую задачу, или оно просто подождет, пока поток не станет доступным? Если он ожидает, как долго он будет ждать?

Комментарии:

1. Рэнди, для чего используется «токен» в этом примере?

2. @Henk — Таким образом, я могу отменить задачу в какой-то момент позже, если захочу.

3. Да, верно. Но какой смысл в отношении «доступных потоков»?

Ответ №1:

Из MSDN:

Вы можете поставить в очередь столько запросов пула потоков, сколько позволяет системная память. Если запросов больше, чем потоков пула потоков, дополнительные запросы остаются в очереди до тех пор, пока потоки пула потоков не станут доступными.

Потоки в управляемом пуле потоков являются фоновыми потоками. То есть их свойства IsBackground верны. Это означает, что поток ThreadPool не будет поддерживать работу приложения после завершения всех потоков переднего плана.

Он будет ждать, пока один из них не будет доступен, или ваше приложение завершит работу.

Ответ №2:

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

Комментарии:

1. Тебе, должно быть, повезло, Люк.. триггер выполняется быстрее, чем ваша собственная тень.

2. Если вы отмените задачу до того, как она получит возможность запуститься, статус задачи изменится с WaitingToRun непосредственно на Cancelled, и задача никогда не будет запущена.

3. @Henk: Я полагаю, что это только в том случае, если задача уже запущена. Я думаю , что он может заметить и самоустраниться, если не дошел до вызова пользовательского кода. Хотя я это не тестировал.

4. @Colin, @Jon, Да, потому что токен также передается в Startnew () здесь.

Ответ №3:

Задача передается планировщику. Планировщик TPL (по умолчанию) управляет несколькими рабочими потоками и назначает задачи этим потокам. Если поток недоступен, ваша задача будет ждать в очереди. Если в очереди слишком много задач, планировщик / threadpool будет медленно создавать новые потоки (со скоростью 2 в секунду).

Вы показываете, но не упоминаете CancellationToken . Это можно использовать только для запроса отмены итак, я подозреваю, что ваш StartTest () будет выполнен, даже если токен был отменен во время постановки задачи в очередь.