在.Net 4.0中,使用Task和线程有什么区别需要注意吗?

18

我更新了代码,用Tasks来代替threads....

根据内存使用和CPU,我没有看到在多核电脑上有任何改进,这是预期的吗?

我的应用程序在运行时基本上会在不同的对象中启动线程/任务...

我所做的只是一个简单的

Task a = new Task(...)
a.Start();

4
我没有注意到任何改进。这很大程度上取决于实际的代码...你甚至可能会看到恶化。 - H H
1
“Tasks”不是神奇的类。最终它们也是“线程”。 - L.B
我认为任务相比线程更加了解多核环境,因此能够在多核上正确分配自己。此外,由于它们使用线程池而无需创建,因此它们更加内存高效。 - TheWommies
@Allen Ho,关于池化带来的性能优势,只有在您经常启动新线程并且它们执行短期任务时才会明显。 - Dan Bryant
5个回答

29

使用Tasks而不是Threads有各种含义,但性能并不是主要问题(假设您不会创建大量的线程)。以下是一些关键的区别:

  1. 默认的TaskScheduler将使用线程池技术,因此某些Tasks可能要等待其他挂起的Tasks完成后才会开始。如果直接使用Thread,则每次使用都会启动一个新线程。
  2. 当Task发生异常时,它会被包装成AggregateException,并在等待Task完成或在Task上注册回调中传递给调用代码。这是因为您还可以执行等待多个任务完成等操作,在这种情况下可能会抛出多个异常并聚合它们。
  3. 如果您未观察到由Task抛出的未处理异常,它最终会通过Task的终结器抛出(可能),这是相当严重的问题。我始终建议挂钩TaskScheduler.UnobservedTaskException事件,以便在应用程序崩溃之前至少记录这些失败情况。这与Thread异常不同,后者会显示在AppDomain.UnhandledException事件中。

谢谢,这是一个很好的概述。我正在研究第一点,使用TaskScheduler听起来很有趣。 - Kosko
1
@Kosko,TaskScheduler 的一个常见用途是 TaskScheduler.FromCurrentSynchronizationContext,它将任务调度到同步上下文(通常是 UI 线程)。这在注册任务的连续操作时最常用,以便连续操作在 UI 线程而不是线程池中运行。它可以帮助避免在 UI 更新方法中出现大量丑陋的 Invoke 代码。 - Dan Bryant

8
如果你仅仅将每个 Thread 的使用替换为 Task,而不做其他更改,我预计几乎会有相同的性能。 Task API 实际上就是这样一个 API,它是对现有构造的 API。在底层,它使用线程来调度其活动,因此具有类似的性能特征。 Task 的好处在于你可以用它们做新的事情:
- 使用 ContinueWith 进行组合 - 取消任务 - 层次结构 - 等等...

2
TPL 摆脱了代码混淆的臃肿。它是每个开发者最终想要编写但没有时间去做的 API。 - Gusdor

4

Takss与Threads相比的一个很大的改进是,您可以轻松地构建任务链。您可以指定任务在前一个任务之后何时开始(“OnSuccess”,“OnError”等),并且可以指定是否应进行同步上下文切换。这为您提供了在后台运行长时间运行的任务,然后在UI线程上运行UI刷新任务的绝佳机会。


0

1
那又怎样?你读过这个问题吗?从内存使用和CPU方面来看,我没有发现多核PC有任何改进,这是正常的吗? - L.B
据我了解,Parallel.Invoke具有更好的多核使用。如果我理解有误,请指教。 - kjennings.dev
  1. 或许 Parallel.Invoke 是用 Tasks 实现的?
  2. “这是预期的吗?”的答案在哪里?
- L.B
我相信...在多核成为行业标准之前,Tasks Api就已经被创建了,据我所知,它从未被重构以有效地处理多核。这基本上就是为什么他们推出了Parallel Api。这只是猜测,但也许他们不想改变Task api,因为它在几个应用程序中被使用。所以他们创建了一个全新的API,并给开发人员提供了选择。抱歉我没有详细解释。认为答案已经在上下文中了。 - kjennings.dev

0

如果您的原始代码或转换后的代码没有完全利用CPU,那么您将会看到差异。例如,如果原始代码始终将线程数限制为2,在四核机器上,使用手动创建的线程将以约50%的负载运行,并且如果您的任务实际上可以并行化,则可能以100%的负载运行。因此,看起来您的原始代码从性能角度来看是合理的,或者两种实现都存在问题,显示出类似的CPU利用不足。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接