views:

7674

answers:

6

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?

+16  A: 

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.

Mitch Wheat
I'd downvote these comments if I could - they're completely off topic and just devalue this site. Let us upvoters deal with those downvoters instead.
bzlm
I'd add that if you have to ask, you're doing something wrong.
Rex M
+3  A: 

I would characterise the thread density of applications something like this:

  • 1-2 threads: desktop application
  • 10-20 threads: server application
  • 100-200 threads: super busy server application (running on serious multicore hardware)
  • 1000+ threads: doesn't happen
Greg Hewgill
I'd change that to "Shouldn't happen", simply because I know that, someone, somewhere has done this.
Matthew Scharley
Based on this chart Microsoft Outlook would be somewhere between a server application and a super busy server application. That's probably about accurate! :)
Jeffrey L Whitledge
I think these numbers are way too generalized to make any sense. A desktop application with a modern GUI could *easily* put good use to more than 2 threads.
bzlm
like the way that you put it :) +1
dr. evil
I might say 1-4 threads for a desktop because you may have one GUI thread, one data worker for the GUI thread, one background refreshing thread for refreshing cached data, and an extra thread to handle something else like communications.
Nazadus
+1  A: 

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.

Ash
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
+1  A: 

I will not provide an answer (Mitch Wheat is right - the limit is determined by address space and stack size you want to allocate to each thread), but rather note that if you are asking this question because you hit the limit, or expect to hit the limit, you should change the design of the program.

Yes, you can create thousands of threads, but it is the wrong way to write application. If you create more than 100-200 threads (and even that number is too big), you should seriously consider using asynchronous programming models. With async API, you don't waste thread for IO, and since your threads are busy doing computations, not waiting for IO completion, there should be no reasons to create more threads than CPUs.

Michael
If you are not providing an answer, make a comment on the question instead.
bzlm
+7  A: 

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.

antonio
A: 

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.

Ian Boyd
-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