Thread.Start()与ThreadPool.QueueUserWorkItem()

And*_*dry 42 .net c# multithreading threadpool

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

那么,有两种方法(基本上):

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 */
Run Code Online (Sandbox Code Playgroud)

2)使用System.Threading.ThreadPool课程.

ThreadPool.QueueUserWorkItem(myfunction, new Object()); /* Same philosophy here */
Run Code Online (Sandbox Code Playgroud)

我应该使用1)或2)有什么特殊原因吗?

  • 表现原因?
  • 模式?
  • 什么是最好的方法?

我有一种感觉,答案是:"视情况而定".能否列举一些方法比另一种更好的情况?

Bri*_*sen 48

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

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

  • 是否有一个很好的参考,演示了当所有项目完成/跟踪进度时如何"观察"线程池? (3认同)

Jim*_*hel 12

托管线程池在不使用线程池时有一些很好的指导.

根据我的经验,您需要在需要持久,专用,长时间运行的线程时创建自己的线程.对于一切,使用异步委托或类似的东西QueueUserWorkItem,BackgroundWorker或者.NET 4.0的任务相关的功能.


Ste*_*eel 7

ThreadPool中的线程是后台线程; 由新Thread对象创建和启动的所有线程都是前台线程.

后台线程不会使托管执行环境保持运行.

有关更多信息,请参阅http://msdn.microsoft.com/en-us/library/h339syd0.aspx.


dan*_*ana 6

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

这似乎是一种替代方案ThreadPool.QueueUserWorkItem.两者的行为相似,但在ASP.NET中使用新方法有一些很好的好处:

HostingEnvironment.QueueBackgroundWorkItem方法允许您安排小型后台工作项.ASP.NET跟踪这些项目并阻止IIS突然终止工作进程,直到所有后台工作项都完成.无法在ASP.NET托管应用程序域之外调用此方法.