3

I got the following error message while downloading using multiple threads:

There were not enough free threads in the ThreadPool to complete the operation.

Should I try to change the default settings for the threadpool in the .net, and how can I do it?

Jeremy Thompson
  • 61,933
  • 36
  • 195
  • 321
Arrabi
  • 3,718
  • 4
  • 26
  • 38
  • 1
    can you show some code? Most likely the solution is **not** to change the size of the thread pool - your problem is somewhere else – BrokenGlass May 05 '11 at 13:20
  • 1
    The default limit depends on the Fx version but is already very high. – H H May 05 '11 at 13:24
  • 1
    how can I replicate the exception you're seeing? Hint: [sscce](http://sscce.org/) – Kiril May 05 '11 at 13:24

4 Answers4

9

Changing the size of the ThreadPool is almost certainly a bad idea (not least: each thread will take another chunk of stack space); you should look instead at your thread usage - are you saturating the pool? You might find TPL and Task[<T>] a better way to handle some async code, or in the cases of things like IO - the Begin* / End* async operations rather than a sync operation on a ThreadPool thread.

You might also check that all your async operations are existing cleanly; are they perhaps stalling (deadlock perhaps) and not exiting?

Finally: the ThreadPool is primarily intended for brief operations (where the spin-up cost of a Thread is most noticeable); long-running operations may do better on dedicated Threads

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • So? what to do? I see it as a normal scenario that at high load there is no free threads in pool. And it's very weird for `WebRequest` class to start throwing exception in normal scenario. – Vlad Aug 09 '17 at 20:50
5

Although this doesn't answer the question directly, it may help someone to avoid this problem. You can use the below to see how many threads are available and make sure you do not exceed it.

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

This will give you the max threads available.

For a description for the different types of threads, have a look at this explanation:

Simple description of worker and I/O threads in .NET

Community
  • 1
  • 1
Talon
  • 3,466
  • 3
  • 32
  • 47
1

You can emulate the program as AspNetServer:

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

See this method System.Net.NclUtilities.IsThreadPoolLow:

if (ComNetOS.IsAspNetServer)
{
    return false;
}

And this System.Net.ComNetOS .ctor():

IsAspNetServer = Thread.GetDomain().GetData(".appDomain") != null;
Irshad
  • 3,071
  • 5
  • 30
  • 51
Nikolay Makhonin
  • 1,087
  • 12
  • 18
1

I'm not sure if this would be the best idea in your situation but if you decide you really need to expand the thread pool this is one way to do it.

 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);

    }
Adrian Zanescu
  • 7,907
  • 6
  • 35
  • 53
  • 1
    This seem to be a [Old shoe or glass bottle](http://weblogs.asp.net/alex_papadimoulis/archive/2005/05/25/408925.aspx) issue. It is much better to just use a hammer like Marc suggests. – Scott Chamberlain May 05 '11 at 13:29
  • This is a direct answer. It might be bad advice. – H H May 05 '11 at 13:38
  • I edited my answer with a disclaimer. It was not intended to be an advice. But if the OP decides this is the best course of action for his situation then my answer is here to help him – Adrian Zanescu May 05 '11 at 13:42
  • This may be the right solution if you need to fix some existing system right now and it's not practical to rework the whole thing. (By the way, the code would be clear with Math.Max and Math.Min rather than the 'if' statements.) – dan-gph Dec 16 '16 at 04:50