使用Task时,如果ThreadPool已满/正忙,会发生什么情况

本文关键字:正忙 什么情况 已满 Task 如果 ThreadPool 使用 | 更新日期: 2023-09-27 18:27:34

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

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

使用Task时,如果ThreadPool已满/正忙,会发生什么情况

在.NET4.0 32位系统上,线程池中的最大线程数设置为约1000个线程。对于较旧版本的.NET来说,这是较少的。如果你有1000个线程在运行,比如说它们由于某种原因而被阻塞,那么当你对第1001个任务进行排队时,它永远不会执行。

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

您可以通过调用ThreadPool.SetMaxThreads方法来更改ThreadPool可以使用的线程数。然而,如果您希望使用这么多线程,那么您的代码就会出现更大的问题。我确实建议您乱用这样的ThreadPool配置。你很可能会得到更糟糕的表现。

请记住,对于TaskThreadPool.QueueUserWorkItem,线程在完成后会被重新使用。如果创建任务或对线程池线程进行排队,则可能会不会创建新线程来执行代码。如果池中已经有可用的线程,它将重用其中一个线程,而不是创建(一个昂贵的)新线程。只有当你在任务中执行的方法永远不会返回时,你才应该担心线程会用完,但正如我所说,这与你的代码完全不同。

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

因此,当所有线程都很忙时,新任务就会排队,而且速度很慢,最多每500毫秒就有一个,TP会分配新线程。

它不会增加MaxThreads。当任务多于可用工作线程时,一些任务将排队等待,直到线程池提供可用线程。它做了一些非常高级的事情来扩展大量的核心(工作窃取、线程注入等)。