ThreadPool.QueueUserWorkItem 与 Task.Factory.StartNew [英] ThreadPool.QueueUserWorkItem vs Task.Factory.StartNew

查看:61
本文介绍了ThreadPool.QueueUserWorkItem 与 Task.Factory.StartNew的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面有什么区别

ThreadPool.QueueUserWorkItem

对比

Task.Factory.StartNew

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

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

解决方案

如果您要使用 TPL 开始一个长时间运行的任务,您应该指定 TaskCreationOptions.LongRunning,这意味着它没有em> 在线程池上调度它.(正如评论中所指出的,这 是特定于调度程序的决定,并不是硬性保证,但我希望任何明智的生产调度程序都能避免调度长时间运行的任务在线程池上.)

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

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

就我个人而言,如果可以选择的话,我肯定会使用 TPL,理由是 Task API 非常好 - 但 do 记得告诉 TPL 你期望长时间运行的任务.

如评论中所述,另请参阅 PFX 团队在 在TPL和线程池之间选择:

<块引用>

最后,我将重申 CLR 团队的 ThreadPool 开发人员已经声明的内容:

<块引用>

Task 现在是将工作排队到线程池的首选方式.

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

What is difference between the below

ThreadPool.QueueUserWorkItem

vs

Task.Factory.StartNew

If the above code is called 500 times for some long running task, does it mean all the thread pool threads will be taken up?

Or will TPL (2nd option) be smart enough to just take up threads less or equal to number of processors?

解决方案

If you're going to start a long-running task with TPL, you should specify TaskCreationOptions.LongRunning, which will mean it doesn't schedule it on the thread-pool. (EDIT: As noted in comments, this is a scheduler-specific decision, and isn't a hard and fast guarantee, but I'd hope that any sensible production scheduler would avoid scheduling long-running tasks on a thread pool.)

You definitely shouldn't schedule a large number of long-running tasks on the thread pool yourself. I believe that these days the default size of the thread pool is pretty large (because it's often abused in this way) but fundamentally it shouldn't be used like this.

The point of the thread pool is to avoid short tasks taking a large hit from creating a new thread, compared with the time they're actually running. If the task will be running for a long time, the impact of creating a new thread will be relatively small anyway - and you don't want to end up potentially running out of thread pool threads. (It's less likely now, but I did experience it on earlier versions of .NET.)

Personally if I had the option, I'd definitely use TPL on the grounds that the Task API is pretty nice - but do remember to tell TPL that you expect the task to run for a long time.

EDIT: As noted in comments, see also the PFX team's blog post on 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.

EDIT: Also from comments, don't forget that TPL allows you to use custom schedulers, if you really want to...

这篇关于ThreadPool.QueueUserWorkItem 与 Task.Factory.StartNew的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆