118

What is the maximum number of threads you can create in a C# application? And what happens when you reach this limit? Is an exception of some kind thrown?


  • The answer will differ if you are running on the x64 VM or the x86 VM - Brian R. Bondy
  • In my situation it's x86, but can you provide the answer for both in case someone else needs it? - creedence.myopenid.com

5 답변


131

There is no inherent limit. The maximum number of threads is determined by the amount of physical resources available. See this article by Raymond Chen for specifics.

If you need to ask what the maximum number of threads is, you are probably doing something wrong.

[Update: Just out of interest: .NET Thread Pool default numbers of threads:

  • 1023 in Framework 4.0 (32-bit environment)
  • 32767 in Framework 4.0 (64-bit environment)
  • 250 per core in Framework 3.5
  • 25 per core in Framework 2.0

(These numbers may vary depending upon the hardware and OS)]


  • How did you figure this out? Do you know what .NET 4.5 is, or what 5.0 will be? - random65537
  • wondering where those number came from - RollRoll
  • You can use this code to get the counts: int workerThreads; int completionPortThreads; ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads); - JALLRED
  • @MitchWheat I was wondering myself, because the linked article doesn't discuss .NET, but plain 'ol C. - pqsk
  • @LoukMo: if you can't create a thread, then you have probably run out of memory! I haven't tried it, but I'm assuming a memory exception will be thrown....? - Mitch Wheat

24

Mitch is right. It depends on resources (memory).

Although Raymond's article is dedicated to Windows threads, not to C# threads, the logic applies the same (C# threads are mapped to Windows threads).

However, as we are in C#, if we want to be completely precise, we need to distinguish between "started" and "non started" threads. Only started threads actually reserve stack space (as we could expect). Non started threads only allocate the information required by a thread object (you can use reflector if interested in the actual members).

You can actually test it for yourself, compare:

    static void DummyCall()
    {
        Thread.Sleep(1000000000);
    }

    static void Main(string[] args)
    {
        int count = 0;
        var threadList = new List<Thread>();
        try
        {
            while (true)
            {
                Thread newThread = new Thread(new ThreadStart(DummyCall), 1024);
                newThread.Start();
                threadList.Add(newThread);
                count++;
            }
        }
        catch (Exception ex)
        {
        }
    }

with:

   static void DummyCall()
    {
        Thread.Sleep(1000000000);
    }

    static void Main(string[] args)
    {
        int count = 0;
        var threadList = new List<Thread>();
        try
        {
            while (true)
            {
                Thread newThread = new Thread(new ThreadStart(DummyCall), 1024);
                threadList.Add(newThread);
                count++;
            }
        }
        catch (Exception ex)
        {
        }
    }

Put a breakpoint in the exception (out of memory, of course) in VS to see the value of counter. There is a very significant difference, of course.


8

i did a test on a 64bit system with c# console, the exception is type of out of memory, using 2949 threads.

I realize we should be using threading pool, which I do, but this answer is in response to the main question ;)


5

You should be using the thread pool (or async delgates, which in turn use the thread pool) so that the system can decide how many threads should run.


  • -1: Thread pool is mentioned in several of the comments. - John Saunders
  • The answer is to let the system decide. - Ian Boyd
  • @Ian: I downvoted you because the same answere was given nine months before. - John Saunders
  • Link. i don't see any mention of thread pool as anyone's answer. - Ian Boyd

4

Jeff Richter in CLR via C#:

"With version 2.0 of the CLR, the maximum number of worker threads default to 25 per CPU in the machine and the maximum number of I/O threads defaults to 1000. A limit of 1000 is effectively no limit at all."

Note this is based on .NET 2.0. This may have changed in .NET 3.5.

[Edit] As @Mitch pointed out, this is specific to the CLR ThreadPool. If you're creating threads directly see the @Mitch and others comments.


  • I think you are referring to the threadpool. - Mitch Wheat
  • You are confusing CLR 2.0 and .NET 2.0 in your comment about .NET 3.5. - bzlm
  • As far as I know the SP1 for .NET 2.0 (part of .NET 3.5) changed the worker threads default to 250 per CPU/core for thread pools. - Michael Damatov

Linked


Related

Latest