线程池通常适用于短时间运行的任务。它有一个限制,即它是应用程序范围内的有限资源(每 CPU 25 个线程),并且有许多内部类使用线程池,因此如果执行大量长时间运行的任务,则会用尽所有线程。
对于长时间运行的任务,最好使用手动创建的线程,并将其背景属性设置为 true。
注意:在 .NET Framework 2.0 版本中,Thread.CurrentPrincipal
属性值会传播到使用 QueueUserWorkItem
方法排队的工作线程。在早期版本中,主体信息不传播。
何时不使用线程池线程
以下情况下,创建和管理自己的线程而不使用线程池线程是合适的:
您需要前台线程。
您需要一个线程具有特定的优先级。
您有导致线程长时间阻塞的任务。线程池有一个最大线程数,因此大量被阻塞的线程池线程可能会防止任务启动。
您需要将线程放入单线程公寓。所有线程池线程都在多线程公寓中。
您需要将稳定的标识与线程关联,或将线程专用于任务。
一个重要区别是:线程池线程上的未处理异常会终止进程;但有三个例外情况:
在线程池线程中抛出 ThreadAbortException
,因为调用了 Abort
。
在线程池线程中抛出 AppDomainUnloadedException
,因为应用程序域正在卸载。
公共语言运行时或宿主进程终止线程。
一些好的参考资料包括:
更新:回应评论。可以使用 GetAvailableThreads
方法来确定线程池中实际线程数。 ThreadPool.GetMaxThreads
是另一种不同的数量。它是请求排队之前池中允许的最大线程数,而不是当前池中实际存在的线程数。
线程池持有一定数量的线程,这些线程可以随时使用,这可能会消除创建新线程的成本,而创建普通线程时就是发生这种情况。