.NET应用程序中的最大线程数?


140

您可以在C#应用程序中创建的最大线程数是多少?当达到此限制时会发生什么?是否抛出某种例外?


如果您在x64 VM或x86 VM上运行,答案将有所不同
Brian R. Bondy

在我的情况下,它是x86,但是如果有人需要它,您能否同时提供答案?

Answers:


145

没有内在的限制。线程的最大数量由可用的物理资源量决定。有关详细信息,请参见Raymond Chen的这篇文章

如果您需要询问最大线程数是多少,可能是您做错了什么。

[ 更新:只是出于兴趣:.NET线程池的默认线程数:

  • 在Framework 4.0(32位环境)中为1023
  • 在Framework 4.0(32位环境)中为32767
  • 框架3.5中的每个核心250个
  • Framework 2.0中每个内核25个

(这些数字可能会因硬件和操作系统而异)]


13
您是如何知道的?您知道什么是.NET 4.5,还是什么将是5.0?
goodguys_activate 2012年

3
您可以使用以下代码获取计数:int workerThreads; intcompletePortPortThreads; ThreadPool.GetMaxThreads(out workerThreads,outcompletePortThreads);
JALLRED

1
@MitchWheat我在想自己,因为链接的文章没有讨论.NET,而是普通的'ol C.
pqsk 2014年

1
@LoukMo:如果您无法创建线程,则可能是内存不足!我还没有尝试过,但是我假设将抛出内存异常。
米奇小麦

1
@Liam现在应该已修复链接。
尤金·科米萨连科

26

米奇是对的。这取决于资源(内存)。

尽管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中的异常(当然是内存不足)中放置一个断点,以查看计数器的值。当然,有很大的不同。


9

我在带有C#控制台的64位系统上进行了测试,例外是内存不足类型,使用2949个线程。

我意识到我们应该使用线程池,但我的回答是针对主要问题;)



4

通过C#在CLR中的Jeff Richter:

“使用CLR 2.0版时,计算机中每个CPU的最大工作线程数默认为25,而I / O线程的最大数默认为1000。限制1000实际上根本没有限制。”

请注意,这是基于.NET 2.0的。在.NET 3.5中可能已更改。

[编辑]正如@Mitch所指出的,这特定于CLR ThreadPool。如果直接创建线程,请参见@Mitch和其他注释。


您在有关.NET 3.5的评论中混淆了CLR 2.0和.NET 2.0。
bzlm

据我所知,.NET 2.0 SP1(.NET 3.5的一部分)将工作线程的默认值更改为线程池的每个CPU /核心250个。
Michael Damatov

0

您可以使用以下代码进行测试

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位应用程序模式。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.