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 VMBrian R. Bondy– Brian R. Bondy2008-09-28 06:07:39 +00:00Commented Sep 28, 2008 at 6:07
-
In my situation it's x86, but can you provide the answer for both in case someone else needs it?creedence.myopenid.com– creedence.myopenid.com2008-09-28 06:10:11 +00:00Commented Sep 28, 2008 at 6:10
-
I am missing an answer what happens when limit is reached. Will app crash or threads remains in waiting queue?Diomos– Diomos2022-10-14 08:49:26 +00:00Commented Oct 14, 2022 at 8:49
7 Answers
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)]
18 Comments
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.
Comments
I would recommend running ThreadPool.GetMaxThreads method in debug
ThreadPool.GetMaxThreads(out int workerThreadsCount, out int ioThreadsCount);
Docs and examples: https://learn.microsoft.com/en-us/dotnet/api/system.threading.threadpool.getmaxthreads?view=netframework-4.8
1 Comment
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.
3 Comments
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.
2 Comments
You can test it by using this snipped code:
private static void Main(string[] args)
{
int threadCount = 0;
try
{
for (int i = 0; i < int.MaxValue; i ++)
{
new Thread(() => Thread.Sleep(Timeout.Infinite)).Start();
threadCount ++;
}
}
catch
{
Console.WriteLine(threadCount);
Console.ReadKey(true);
}
}
Beware of 32-bit and 64-bit mode of application.