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 Sep 28 '08 at 06:07
-
In my situation it's x86, but can you provide the answer for both in case someone else needs it? – Sep 28 '08 at 06:10
-
I am missing an answer what happens when limit is reached. Will app crash or threads remains in waiting queue? – Diomos Oct 14 '22 at 08: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)]

- 1,533
- 11
- 25

- 295,962
- 43
- 465
- 541
-
18How did you figure this out? Do you know what .NET 4.5 is, or what 5.0 will be? – makerofthings7 Oct 21 '12 at 13:31
-
5You can use this code to get the counts: int workerThreads; int completionPortThreads; ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads); – JALLRED Jun 09 '14 at 17:03
-
@MitchWheat a summary of the link would be great, in the case when the page is no longer available. – pqsk Dec 22 '14 at 20:26
-
-
1@MitchWheat I was wondering myself, because the linked article doesn't discuss .NET, but plain 'ol C. – pqsk Dec 23 '14 at 01:47
-
This is backed up by Joe Albahari. http://www.albahari.com/threading/#_Optimizing_the_Thread_Pool – Kana Ki Nov 19 '17 at 22:57
-
@MitchWheat This goes over worker threads, how is the determination made for IO(PortCompletion) Threads – johnny 5 Jan 23 '18 at 22:30
-
@johnny: this question is 9 years old: I'd suggest you ask a new specific question. – Mitch Wheat Jan 23 '18 at 23:27
-
Just out of curiosity, what happens when your application hits the maximum number of thread possible?? Does it become unresponsive and just closes by itself?? If it's a c# windows form app, does the form shown becomes grayed out and closes after?? – LoukMouk Aug 01 '18 at 12:00
-
1@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 Aug 01 '18 at 12:29
-
@MitchWheat in Framework 4.0 and above on 64-bit environment is 32767, not 32768. You can check it easly using this code: `ThreadPool.GetMaxThreads(out var maxWorkerThreads, out var maxCompletionPortThreads);` where value of `maxWorkerThreads` is the is the value which we are looking for. – B.Kosmowski Oct 09 '18 at 20:00
-
@B.Kosmowski: ThreadPool.GetMaxThreads() "Retrieves the number of requests to the thread pool that can be active concurrently" – Mitch Wheat Oct 10 '18 at 00:45
-
-
1
-
I down voted just because of the comment "If you need to ask what the maximum number of threads is, you are probably doing something wrong. ". – matan justme Jan 23 '22 at 13:37
-
@matan justme : then you have gaps in your knowledge. That statement is correct. – Mitch Wheat Jan 24 '22 at 03:01
-
There is also a SetMaxThreads(...) method. See https://learn.microsoft.com/en-us/dotnet/api/system.threading.threadpool.setmaxthreads?view=net-7.0 – Markus May 29 '23 at 14:30
-
@Markus : SetMaxThreads(...) might not do what you might expect it to ..... – Mitch Wheat May 29 '23 at 23:32
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.

- 673
- 7
- 10
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

- 536
- 8
- 18
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.

- 246,734
- 253
- 869
- 1,219
-
-
@Ian: I downvoted you because the same answere was given nine months before. – John Saunders Sep 09 '09 at 06:13
-
12
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.

- 60,973
- 31
- 151
- 169
-
-
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 Oct 02 '08 at 19:46
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.

- 4,532
- 4
- 53
- 64