c# - ThreadPool.QueueUserWorkItem 与 Task.Factory.StartNew

标签 c# multithreading c#-4.0 task-parallel-library threadpool

下面有什么区别

ThreadPool.QueueUserWorkItem

对比

Task.Factory.StartNew

如果上面的代码被某个长时间运行的任务调用了500次,是否意味着所有的线程池线程都会被占用?

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

最佳答案

如果您要使用 TPL 启动长时间运行的任务,您应该指定 TaskCreationOptions.LongRunning ,这意味着它不会在线程池上安排它。 (编辑:如评论中所述,这 是一个特定于调度程序的决定,并不是硬性保证,但我希望任何明智的生产调度程序都能避免调度长时间运行的任务在线程池上。)

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

线程池的目的是避免 任务因创建新线程而受到很大的影响,与它们实际运行的时间相比。如果任务将运行很长时间,创建新线程的影响无论如何都会相对较小——而且您不希望最终可能用完线程池线程。 (现在不太可能了,但我确实在早期版本的 .NET 上体验过它。)

就我个人而言,如果我有选择,我肯定会使用 TPL,因为 Task API 非常好 - 但记得告诉 TPL 你期望长时间运行的任务。

编辑:如评论中所述,另请参阅 PFX 团队关于 choosing between the TPL and the thread pool 的博客文章:

In conclusion, I’ll reiterate what the CLR team’s ThreadPool developer has already stated:

Task is now the preferred way to queue work to the thread pool.

编辑:同样来自评论,不要忘记 TPL 允许您使用 custom schedulers , 如果你真的想...

关于c# - ThreadPool.QueueUserWorkItem 与 Task.Factory.StartNew,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9200573/

相关文章:

c# - CurrentCulture with async/await,自定义同步上下文

c#-4.0 - 如何在 Xamarin Forms 中更改 Windows Phone 上工具栏的背景颜色?

c# - .net WCF GET HTTPS 400 错误请求,但与 Http 一起工作正常

c# - C#中使用is关键字声明变量内联

c# - 在 C# 窗体中将密码存储更改为哈希存储

c# - 好的类设计实例

c# - 如何生成与以前在 C# 中随机生成的 key 相同的 key

c# - 如何告诉 Range.NumberFormat 按原样放置数据?

c# - Parallel.ForEach 中的异常堆栈跟踪和聚合

c++ - 挂起时线程内存发生变化