«В ThreadPool было недостаточно свободных потоков для завершения операции». - PullRequest
3 голосов
/ 05 мая 2011

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

Недостаточно свободных тем в ThreadPool для завершения работа.

Стоит ли пытаться изменить настройки по умолчанию для пула потоков в .net и как я могу это сделать?

Ответы [ 4 ]

9 голосов
/ 05 мая 2011

Изменение размера ThreadPool почти наверняка является плохой идеей (не в последнюю очередь: каждый поток займет другой кусок стекового пространства); вместо этого вы должны посмотреть на использование потоков - насыщаете ли вы пул? Вы могли бы найти TPL и Task[<T>] лучшим способом обработки некоторого асинхронного кода, или в таких случаях, как IO - асинхронные операции Begin* / End*, а не операция синхронизации в потоке ThreadPool.

Вы также можете проверить, что все ваши асинхронные операции существуют чисто; возможно, они останавливаются (возможно, в тупике) и не выходят?

Наконец: ThreadPool - это , в основном , предназначенный для коротких операций (где стоимость раскрутки Thread наиболее заметна); длительные операции могут быть лучше на выделенных Thread s

4 голосов
/ 26 ноября 2015

Хотя это не дает прямого ответа на вопрос, оно может помочь кому-то избежать этой проблемы. Вы можете использовать ниже, чтобы увидеть, сколько потоков доступно и убедитесь, что вы не превышаете его.

int workerThreads, cmpThreads;
ThreadPool.GetAvailableThreads(out workerThreads, out cmpThreads);

Это даст вам максимальное количество доступных тем.

Для описания различных типов потоков, посмотрите на это объяснение:

Простое описание рабочих потоков и потоков ввода / вывода в .NET

1 голос
/ 13 августа 2015

Вы можете эмулировать программу как AspNetServer:

if (Thread.GetDomain().GetData(".appDomain") == null)
{
    Thread.GetDomain().SetData(".appDomain", new object());
}

См. Этот метод System.Net.NclUtilities.IsThreadPoolLow:

if (ComNetOS.IsAspNetServer)
{
    return false;
}

А это System.Net.ComNetOS .ctor():

IsAspNetServer = Thread.GetDomain().GetData(".appDomain") != null;
1 голос
/ 05 мая 2011

Я не уверен, что это будет лучшей идеей в вашей ситуации, но если вы решите, что вам действительно нужно расширить пул потоков, это один из способов сделать это.

 public static void ExpandThreadPool(int minThreads,int maxThreads)
    {
        int workerThreads, cmpThreads;

        ThreadPool.GetMaxThreads(out workerThreads, out cmpThreads);
        if (workerThreads < maxThreads)
        {
            workerThreads = maxThreads;
        }
        ThreadPool.SetMaxThreads(workerThreads, cmpThreads);

        ThreadPool.GetMinThreads(out workerThreads, out cmpThreads);
        if (workerThreads < minThreads)
        {
            workerThreads = minThreads;
        }
        ThreadPool.SetMinThreads(workerThreads, cmpThreads);

    }
...