在 C # 应用程序中最多可以创建多少个线程?当你达到这个极限时会发生什么?抛出某种异常吗?
没有固有的限制。线程的最大数量由可用物理资源的数量决定。详情请参阅 作者: Raymond Chen。
如果您需要询问线程的最大数量是多少,那么您可能是做错了什么。
[ 更新: 只是出于兴趣: . NET 线程池默认线程数:
(这些数字可能因硬件和操作系统而异)]
Jeff Richter in CLR via C # :
”在 CLR 的2.0版本中,最大的 工作线程的数量默认为机器中每个 CPU 25个 以及 I/O 的最大数量 线程默认为1000,1000的限制实际上是没有限制的。”
注意,这是基于.NET 2.0的。这在.NET 3.5中可能已经改变了。
正如@Mitch 指出的,这是特定于 CLR ThreadPool 的。如果您正在创建线程,请直接查看@Mitch 和其他注释。
Mitch 是对的,这取决于资源(内存)。
虽然 Raymond 的文章是专门讨论 Windows 线程,而不是 C # 线程,但逻辑也是一样的(C # 线程映射到 Windows 线程)。
然而,正如我们在 C # 中一样,如果我们想要完全精确,我们需要区分“已启动”和“未启动”线程。实际上,只有已启动的线程才会保留堆栈空间(正如我们所预期的那样)。非启动线程只分配线程对象所需的信息(如果对实际成员感兴趣,可以使用反射器)。
你可以亲自测试一下,比较一下:
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) { } }
与:
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) { } }
在 VS 中的异常(当然是内存不足)中放置一个断点,以查看 counter 的值。当然,两者之间存在着非常显著的差异。
您应该使用线程池(或异步委托,而异步委托又使用线程池) ,以便系统可以决定应该运行多少个线程。
我用 c # 控制台在一个64位系统上做了一个测试,异常是内存不足的类型,使用了2949个线程。
我意识到我们应该使用线程池,我也是这样做的,但是这个答案是对主要问题的回应;)
你可以使用下面这段代码来进行 测试:
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); } }
小心32位和64位的应用模式。
我建议在调试中运行 ThreadPool.GetMaxThreads 方法
ThreadPool.GetMaxThreads(out int workerThreadsCount, out int ioThreadsCount);
文件及例子: Https://learn.microsoft.com/en-us/dotnet/api/system.threading.threadpool.getmaxthreads?view=netframework-4.8