.Net 4.0 Tasks是否应该是多线程应用程序的首选方法?

时间:2011-11-21 22:54:23

标签: .net multithreading threadpool task-parallel-library

我正在阅读Task Parallel Library并且文章说:

  

在.NET Framework 4中,任务是编写多线程,异步和并行代码的首选API

但它也表示他们在幕后使用ThreadPool。我难以弄清楚的是,如果只在你使用ThreadPool时使用Tasks(因此“Thread vs. Task”等同于“Thread与ThreadPool”相同),或者Microsoft是否打算使用Tasks需要多个线程的地方,没有“Thread与ThreadPool”困境所固有的考虑因素。

那么,在任何需要多个线程的地方使用任务吗?

3 个答案:

答案 0 :(得分:4)

使用任务的设计优势在于您将线程的细节移交给运行时,这可能使用较少的错误,更优化的解决方案来完成线程任务。我知道某些基于任务的范例,比如PLINQ,允许你提示运行时应该采用哪种策略,这样就可以直接处理“to Threadpool or to Threadpool”的问题。

切换到此模型类似于切换到Managed GC-ed语言而不是需要您清理自己内存的语言。总会有一些支持后者的论据,但垃圾收集现在变得如此优化,因为它实际上是一个非问题。理想情况下,Tasks的运行时切换机制将发展并变得更好。因此从理论上讲,为.NET 4编写和编译的应用程序可以通过更好的运行时实现获得更快,而无需进一步重新编译。此外,众所周知,线程代码很难正确,因此任何隐藏这些细节的机制对程序员都有好处。

这些好处是否超过潜在的损害,例如运行时不能很好处理的边缘情况,应该逐案考虑。不过,我当然会尽量不在这里进行优化。

答案 1 :(得分:1)

您可以使用TaskCreationOptions.LongRunning作为提示告诉TPL您的任务可能比ThreadPool调整的任务更复杂。但是,是的,TPL似乎确实是未来多线程编程的首选方法。微软甚至建立在它之上,以支持Async CTP中提出的新asyncawait关键字。这并不意味着您必须完全放弃旧样式ThreadThreadPool API。但是,我个人发现TPL在更优雅的API中完成了我想要的大部分工作,而且我现在几乎完全依赖它。

答案 2 :(得分:0)

Task是比线程或ThreadPool更高级的抽象。基本上,您在一个Task中打包一个函数,并要求运行时尽可能地执行它。如果不是由有限数量的线程执行的任务的过程,您可以拥有许多数十个。

使用任务,开发人员根据需要创建任意数量的任务,将它们链接起来创建流(F#中的工作流)并控制它们的取消,而不必担心线程的分配或使用方式。运行时可以选择使用有限数量的线程执行所有任务的最佳方法。

任务使并发编程模式的实现变得更加容易。 ParallelExtensionExtras库提供了将Begin / EndXXX对转换为可链接的任务的方法,以及Async CTP用于提供async / await语法的Task迭代习惯用法的初步版本。您可以使用ConcurrentCollection任务来创建作业队列,类似于ParallelExtensionExtras中的AsyncCall示例,或者更进一步创建类似于Scala,Erlang或F#的代理。 Async CTP中的DataFlow是您可以使用任务创建的另一个示例。

您必须记住,虽然典型的笔记本电脑有2个内核而典型的台式机有4个,但小型服务器已经拥有8个或更多内核,很快就会拥有更多内核。通过手动调度线程和避免阻塞来保持所有这些核心繁忙可能会成为一个主要问题。