使用线程池和普通线程有什么区别?

时间:2009-06-29 14:09:13

标签: .net multithreading

我在SO上阅读随机问题和答案,并遇到了这个问题:

C#, IAsyncResult and the thread pool

问的问题是使用线程池的X方法还是使用普通线程。

使用线程池和普通线程有什么区别?

4 个答案:

答案 0 :(得分:21)

线程池通常适用于短期运行的任务。它有一个限制,它是一个应用程序范围的有限资源(每个CPU 25个),并且有很多内部类使用threadpoool,所以如果你执行很多长时间运行的任务,你将耗尽所有线程。

对于长时间运行的任务,最好使用手动创建的线程,其background属性设置为true。

注意:在.NET Framework 2.0版中,Thread.CurrentPrincipal属性值将传播到使用QueueUserWorkItem方法排队的工作线程。在早期版本中,不传播主体信息。

何时不使用线程池线程

有几种情况适合创建和管理自己的线程而不是使用线程池线程:

  • 您需要前台线程(!)。

  • 您需要一个具有特定优先级的线程。

  • 您的任务导致线程长时间阻塞。线程池具有最大线程数,因此大量被阻塞的线程池线程可能会阻止任务启动。

  • 您需要将线程放入单线程单元中。所有ThreadPool线程都在多线程单元中。

  • 您需要具有与该线程关联的稳定标识,或将线程专用于任务。

一个很大的区别是线程池线程上的未处理异常终止进程;除了以下三个例外:

  • 由于ThreadAbortException被调用,因此在线程池线程中抛出Abort

  • 在线程池线程中抛出AppDomainUnloadedException,因为正在卸载应用程序域。

  • 公共语言运行库或主机进程终止该线程。

一些很好的参考资料是:

The Managed Thread Pool

Threading in C#

Programming the Thread Pool in the .NET Framework

更新:回复评论。您可以使用GetAvailableThreads方法在任何给定时间确定线程池中的实际线程数。 ThreadPool.GetMaxThreads是一个不同的数量。它是在请求排队之前池中允许的最大值,而不是当前池中的实际线程数。

答案 1 :(得分:7)

差异不在线程本身之间,因为它们的行为相同,不同之处在于谁管理线程的生命周期,以及如何使用它们。

.net中的线程池是一个线程池,它会增长或缩小,当您为线程池进行处理队列时,它将确定是否需要启动新线程或将重用现有线程。您不必显式创建线程。

这很不错,但这样做的缺点是线程池中可用的线程数量有限,因此如果排队长时间运行的任务,这可能会对您的应用程序产生负面影响,因为您可能正在使用线程池其他人可能想要使用的线程。

有关线程池的信息,请参阅此article

答案 2 :(得分:3)

ThreadPool包含许多可供您使用的线程,这可以消除创建新线程的成本,这就是创建普通线程时会发生的情况。

答案 3 :(得分:0)

线程池创建线程并且assigsn工作到自由线程。这样就可以预防为每个工作项创建和处理线程,因为创建和处理线程是一项相对昂贵的操作。