我在SO上阅读随机问题和答案,并遇到了这个问题:
C#, IAsyncResult and the thread pool
问的问题是使用线程池的X方法还是使用普通线程。
使用线程池和普通线程有什么区别?
答案 0 :(得分:21)
线程池通常适用于短期运行的任务。它有一个限制,它是一个应用程序范围的有限资源(每个CPU 25个),并且有很多内部类使用threadpoool,所以如果你执行很多长时间运行的任务,你将耗尽所有线程。
对于长时间运行的任务,最好使用手动创建的线程,其background属性设置为true。
注意:在.NET Framework 2.0版中,Thread.CurrentPrincipal
属性值将传播到使用QueueUserWorkItem
方法排队的工作线程。在早期版本中,不传播主体信息。
何时不使用线程池线程
有几种情况适合创建和管理自己的线程而不是使用线程池线程:
您需要前台线程(!)。
您需要一个具有特定优先级的线程。
您的任务导致线程长时间阻塞。线程池具有最大线程数,因此大量被阻塞的线程池线程可能会阻止任务启动。
您需要将线程放入单线程单元中。所有ThreadPool线程都在多线程单元中。
您需要具有与该线程关联的稳定标识,或将线程专用于任务。
一个很大的区别是线程池线程上的未处理异常终止进程;除了以下三个例外:
由于ThreadAbortException
被调用,因此在线程池线程中抛出Abort
。
在线程池线程中抛出AppDomainUnloadedException
,因为正在卸载应用程序域。
公共语言运行库或主机进程终止该线程。
一些很好的参考资料是:
Programming the Thread Pool in the .NET Framework
更新:回复评论。您可以使用GetAvailableThreads
方法在任何给定时间确定线程池中的实际线程数。 ThreadPool.GetMaxThreads
是一个不同的数量。它是在请求排队之前池中允许的最大值,而不是当前池中的实际线程数。
答案 1 :(得分:7)
差异不在线程本身之间,因为它们的行为相同,不同之处在于谁管理线程的生命周期,以及如何使用它们。
.net中的线程池是一个线程池,它会增长或缩小,当您为线程池进行处理队列时,它将确定是否需要启动新线程或将重用现有线程。您不必显式创建线程。
这很不错,但这样做的缺点是线程池中可用的线程数量有限,因此如果排队长时间运行的任务,这可能会对您的应用程序产生负面影响,因为您可能正在使用线程池其他人可能想要使用的线程。
有关线程池的信息,请参阅此article
答案 2 :(得分:3)
ThreadPool包含许多可供您使用的线程,这可以消除创建新线程的成本,这就是创建普通线程时会发生的情况。
答案 3 :(得分:0)
线程池创建线程并且assigsn工作到自由线程。这样就可以预防为每个工作项创建和处理线程,因为创建和处理线程是一项相对昂贵的操作。