ThreadPool.QueueUserWorkItem与Task.Factory.StartNew

sta*_*ser 76 c# multithreading threadpool c#-4.0

下面有什么区别

ThreadPool.QueueUserWorkItem
Run Code Online (Sandbox Code Playgroud)

VS

Task.Factory.StartNew
Run Code Online (Sandbox Code Playgroud)

如果对于某些长时间运行的任务调用上述代码500次,是否意味着将占用所有线程池线程?

或者TPL(第二选项)是否足够聪明,只能占用少于或等于处理器数量的线程?

Jon*_*eet 91

如果你要用TPL开始一个长期运行的任务,你应该指定TaskCreationOptions.LongRunning,这意味着它不会在线程池上安排它.(编辑:正如评论中所述,这一个特定于调度程序的决策,并不是一个硬性和快速的保证,但我希望任何合理的生产调度程序都可以避免在线程池上安排长时间运行的任务.)

你绝对不应该自己在线程池上安排大量长时间运行的任务.我相信这些天线程池的默认大小非常大(因为它经常以这种方式滥用)但从根本上说它不应该像这样使用.

线程池的重点是避免与创建新线程相比较的任务与实际运行时相比.如果任务将运行很长时间,那么创建新线程的影响无论如何都会相对较小 - 并且您不希望最终可能耗尽线程池线程.(现在不太可能,但我确实在早期版本的.NET上体验过它.)

就个人而言,如果我有选择权,我肯定会使用TPL,理由是TaskAPI非常好 - 但记得告诉TPL你希望任务能够运行很长时间.

编辑:如评论中所述,另请参阅PFX团队关于在TPL和线程池之间进行选择的博客文章:

总之,我将重申CLR团队的ThreadPool开发人员已经说过的内容:

Task is now the preferred way to queue work to the thread pool.
Run Code Online (Sandbox Code Playgroud)

编辑:同样来自评论,不要忘记TPL允许您使用自定义调度程序,如果你真的想......

  • 我对'TaskCreationOptions.LongRunning`将始终避免线程池的严格规则保持警惕.它似乎更像是一个指令,而不是一个实现保证.我是不是基于那个? (4认同)
  • @Marc:嗯,这取决于调度程序 - 但是在线程池 IMO 上明确安排长时间运行的任务将是一个非常疯狂的调度程序。 (2认同)