【问题标题】:When is the System.Threading.Task useful?System.Threading.Task 什么时候有用?
【发布时间】:2012-07-22 00:00:49
【问题描述】:

我已经广泛使用了大部分 Threading 库。我对创建新线程、创建 BackgroundWorker 和使用内置的 .NET ThreadPool 非常熟悉(这些都非常酷)。

但是,我从来没有找到使用Task 类的理由。我可能看到过一两个使用它们的例子,但这些例子不是很清楚,也没有给出一个高层次的概述,说明为什么应该使用一个任务而不是一个新线程。

问题 1:从高层次来看,在 .NET 中使用任务与使用其他并行处理方法之一相比何时有用?

问题 2:有没有人有一个简单和/或中等难度的例子来演示如何使用任务?

【问题讨论】:

  • 任务往往更易于使用,尤其是当您将它们视为尚未完成的工作的承诺时。
  • 任务(和 TPL)允许进一步抽象 [a]sync 操作。已经存在/曾经是 IAsyncResult 接口(BeginXYZ/EndXYZ 经常使用它,Task 也使用它),但使用起来有点尴尬。 Task 类提供了一种常见的“反转”技术; Task 可以执行“普通”代码,而不是创建新的 IAsyncResult 类型。
  • 我认为您的问题 2 不适合 SO。
  • @William 我不确定,但我认为“给我看一个 X 的例子”实际上不是一个问题,所以它不属于像 SO 这样的问答。
  • @svick - 我知道这个问题不是很具体,但这是我知道可能需要学习的情况之一,但我不知道如何问正确提问。我认为你下面的答案很完美!

标签: c# multithreading parallel-processing task-parallel-library task


【解决方案1】:

使用Tasks 有两个主要优势:

  1. Task 可以表示将来可用的任何结果(一般概念并不特定于.Net,它被称为future),而不仅仅是计算。这对于async-await 尤其重要,它使用Tasks 进行异步操作。由于得到结果的操作可能会失败,Tasks 也可以代表失败。
  2. Task 有很多方法可以对它们进行操作。您可以同步等待它完成(Wait()),等待它的结果(Result),在Task 完成时设置一些操作(ContinueWith())以及一些适用于多个Tasks 的方法(WaitAll()WaitAny()ContinueWhenAll())。所有这些都可以使用其他并行处理方法实现,但您必须手动完成。

使用Task还有一些较小的优势:

  1. 您可以使用自定义TaskScheduler 来决定Task 运行的时间和位置。例如,如果您想 run a Task on the UI threadlimit the degree of parallelismhave a Task-level readers–writer lock,这可能很有用。
  2. Tasks 支持通过CancellationToken 合作取消。
  3. 代表计算的Tasks 有一些性能改进。例如,它们使用工作窃取队列来提高处理效率,并且还支持内联(在同步等待的线程上执行尚未开始的 Task)。

【讨论】:

  • +1,很好的答案。但是,我认为“较小的 #1”是主要优势,并将“自定义”替换为“特定”。有两种常用的内置 TaskScheduler,一种用于后台任务,可以在任何 ThreadPool 线程上运行,另一种用于必须在特定 SynchronizationContext 中运行的代码,例如在 UI 线程上。第 2 点:您无需编写自定义调度程序即可使用此功能。第 1 点:相同的模型可以用于未来工作的前景和背景单元,这是一个巨大的好处。
  • 一个复杂的概念用简单明了的英语回答,脱帽致敬!
猜你喜欢
  • 2011-09-28
  • 2012-08-07
  • 2012-04-05
  • 1970-01-01
  • 2011-09-06
  • 2010-12-26
  • 2012-08-18
  • 2011-05-06
  • 2012-05-24
相关资源
最近更新 更多