Task.Factory.StartNew запускается с большой задержкой, несмотря на наличие доступных потоков в пуле потоков - PullRequest
0 голосов
/ 03 декабря 2018

Этот вопрос является продолжением предыдущего вопроса, который я задавал:

Требуется больше нескольких секунд для запуска задания

Я сейчасзнать, как именно воспроизвести этот сценарий.Task.Factory.StartNew запланирован в пуле потоков, поэтому я регистрирую следующее (непосредственно перед вызовом Factory.StartNew):

        int workerThreads = 0;
        int completionPortThreads = 0;
        ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
        ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
        var tokenSource = new CancellationTokenSource();
        CancellationToken token = tokenSource.Token;
         //I HAVE A LOG HERE

        Task task = Task.Factory.StartNew(() =>
        {
          //I HAVE A LOG ALSO HERE, AND THAT'S HOW I KNOW,    
          //THE TASK INVOCATION IS DELAYED, AND THE DALAY IS NOT DUE TO MY CODE WITHIN THE TASK
           // Some action that returns a boolean - **CODE_A**
        }).ContinueWith((task2) =>
        {
            result= task2.Result;
            if (!result)
            {
                //Another action **CODE_B**
            }
        }, token);

При воспроизведении ошибки я получаю 32767 как Макс.рабочие потоки и 32756 как доступные рабочие потоки.

Теперь есть кое-что, чего я не понимаю.По крайней мере, как я понял, как только пул потоков достигнет своей перегрузки, пул потоков немедленно прекратит создавать новые потоки.И это, вероятно, причина задержки моей задачи (которая начинается более чем через 5 секунд после вызова Factory.StartNew).

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

Доступные потоки находятся в ThreadPool (я имею в виду, я вызываю ThreadPool .GetAvailableThreads), а Task.Factory.StartNew выделяет задачу из threadPool.Итак, почему я получаю эту задержку, несмотря на наличие доступных потоков в пуле потоков?

1 Ответ

0 голосов
/ 03 декабря 2018

Это не значение MAX для рабочих потоков, на которое нужно смотреть, а значение MIN, которое вы получаете через ThreadPool.GetMinThreads().

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

Вы можете изменить минимальное количество потоков, если это абсолютно необходимо (а это в некоторых случаях), но, вообще говоря, если вам это нужно, вам, возможно, придется подумать о редизайне своей многопоточности, чтобы вы

Как Документация Microsoft гласит: :

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

...