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

时间:2012-03-13 16:45:05

标签: c# .net asynchronous task-parallel-library

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

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

3 个答案:

答案 0 :(得分:8)

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

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

您可以通过调用ThreadPool.SetMaxThreads方法更改ThreadPool可以使用的线程数。但是,如果您希望使用那么多线程,则代码中存在更大的问题。我做 NOT 建议你乱用ThreadPool这样的配置。你最有可能只是表现更差。

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

答案 1 :(得分:7)

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

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

答案 2 :(得分:5)

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