2011-05-31 56 views
36

Microsoft .NET Base Class Library提供了几种创建线程并启动它的方法。基本上,调用与其他提供相同类型服务的调用非常相似:创建一个表示执行流(或更多)的对象,为其分配一个代表要执行的执行流的委托,并最终根据委托签名取决于对象作为参数。Thread.Start()与ThreadPool.QueueUserWorkItem()

那么,有两种方法(主要):

1)使用System.Threading.Thread类。

Thread curr = new Thread(myfunction); /* In a class, myfunction is a void taking an object */ 
curr.Start(new Object()); /* Or something else to be downcast */ 

2)使用System.Threading.ThreadPool类。

ThreadPool.QueueUserWorkItem(myfunction, new Object()); /* Same philosophy here */ 

是否有任何特殊原因为什么我应该使用1)或2)?性能原因?模式?什么是最好的方法?

我有一种感觉,答案是:“依情况而定”。你能否列举出一种方法比另一种更好的情况?

+0

http://stackoverflow.com/questions/1506838/backgroundworker-vs-background-thread/1507337#1507337 – 2011-05-31 20:13:47

回答

42

开始一个新的线程可能是一个非常昂贵的操作。线程池重用线程,从而分摊成本。除非需要专用线程,否则线程池是推荐的方式。通过使用专用线程,您可以更好地控制线程特定的属性,例如优先级,文化等。此外,您不应该在线程池上执行长时间运行的任务,因为它会强制池产生其他线程。

除了你提到的选项,.NET 4还提供了一些很好的并发抽象。查看Task和Parallel类以及所有新的PLINQ方法。

+3

是否有演示如何“看”所有项目的时候线程池一个很好的参考完成/跟踪进度? – jocull 2014-03-17 15:31:06

2

使用ThreadPool,您对线程系统的控制较少。这是一个权衡以简化您的过程。如果您拥有ThreadPool所需的全部内容,则可以随意使用它。如果你需要更多的线程控制,那么你当然需要使用Thread类。

1

ThreadPool.QueueUserWorkItem()基本上用于即发即用的情况,当应用程序不依赖于操作是否完成时。

使用经典线程进行细粒度控制。

11

The Managed Thread Pool在不使用线程池时有一些非常好的指导原则。

根据我的经验,当您需要持久的,专用的,长时间运行的线程时,您希望创建自己的线程。对于其他任何事情,请使用异步委托或类似QueueUserWorkItemBackgroundWorker或.NET 4.0的任务相关功能。

+1

QueueUserWorkItem?它不只是线程池? :) – 2013-05-08 13:45:22

5

在.NET 4.5.2中,他们添加了一个新方法:HostingEnvironment.QueueBackgroundWorkItem

这似乎是ThreadPool.QueueUserWorkItem的替代方案。这两种行为类似,但在ASP.NET工作时,有使用新的方法,一些不错的优势:

的HostingEnvironment.QueueBackgroundWorkItem方法可以让你 赛程小背景的工作项目。 ASP.NET跟踪这些项目,并且 可以防止IIS突然终止工作进程,直到完成所有 后台工作项目。在ASP.NET托管应用程序域之外,不能将此方法称为 。

相关问题