使用Task时,如果ThreadPool满/忙,会发生什么?

当我使用使用ThreadPool的.Net 4 Task类时,如果所有线程都忙,会发生什么?

TaskScheduler是否创建了一个新线程并扩展了ThreadPool最大线程数,或者它是否等待直到线程可用?

在.NET4.0 32位系统上,ThreadPool中的最大线程数设置为大约1000个线程。 对于旧版本的.NET来说,它更少。 如果你有1000个线程,说它们由于某种原因而阻塞,当你排队第1001个任务时,它就不会执行。

在32位进程中,您永远不会达到最大线程数。 请记住,每个线程占用至少1MB的内存(这是用户模式堆栈的大小),以及任何其他开销。 您已经从CLR和加载的本机DLL中丢失了大量内存,因此在使用那么multithreading之前,您将遇到OutOfMemoryException。

您可以通过调用ThreadPool.SetMaxThreads方法来更改ThreadPool可以使用的ThreadPool.SetMaxThreads 。 但是,如果您希望使用那么multithreading,那么您的代码就会遇到更大的问题。 我建议你不要乱用ThreadPool这样的配置。 你最有可能只是表现更差。

请记住TaskThreadPool.QueueUserWorkItem ,线程在完成后重新使用。 如果您创建任务或队列线程池线程,它可能会可能不会创建一个新线程来执行您的代码。 如果池中已有可用线程,它将重用其中一个而不是创建(昂贵的)新线程。 只有当您在任务中执行的方法永远不会返回时,您是否应该担心线程耗尽,但就像我说的那样,这与您的代码完全不同。

默认情况下,ThreadPool的MaxThreads非常高。 通常你永远不会到达那里,你的应用程序将首先崩溃。

因此,当所有线程都忙时,新任务排队并缓慢排列,每500毫秒最多1个,TP将分配新线程。

它不会增加MaxThreads。 当任务多于可用工作线程时,某些任务将排队等待,直到线程池提供可用线程。 它做了一些非常先进的东西,可以扩展大量的内核(工作窃取,线程注入等)。