我应该注意到在.Net 4.0中使用任务与线程的区别吗?

我更新了我的代码以使用Tasks而不是线程….

看看内存使用情况和CPU我没有注意到多核PC的任何改进,这是预期的吗?

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

我所做的一切都很简单

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

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

  1. 默认的TaskScheduler将使用线程池,因此在完成其他待处理任务之前,某些任务可能无法启动。 如果直接使用Thread,每次使用都会启动一个新的Thread。
  2. 当任务中发生exception时,它会被包装到一个AggregateException中,调用代码在等待任务完成时或者在Task上注册一个continuation时可以接收。 这是因为您还可以执行等待多个任务完成的操作,在这种情况下,可以抛出并聚合多个exception。
  3. 如果你没有观察到一个Task抛出的未处理的exception,那么它(最终可能)最终会被Task的终结器抛出,这特别令人讨厌。 我总是建议挂钩TaskScheduler.UnobservedTaskException事件,这样你至少可以在应用程序爆炸之前记录这些失败。 这与线程exception不同,后者出现在AppDomain.UnhandledException事件中。

如果你只是简单地用Thread替换了Thread每一个用法并且没有做任何其他的改变,我会期望几乎相同的性能。 Task API就是这样,它是现有一组构造的API。 在引擎盖下,它使用线程来安排它的活动,因此具有类似的性能特征。

Task是你可以用它们做的新事物

  • ContinueWith
  • 消除
  • 层次结构
  • 等……

Takss vs. Threads的一个重大改进是你可以轻松地构建任务链。 您可以指定任务应在上一个任务之后启动的时间(“OnSuccess”,“OnError”,aso),您可以指定是否应该有同步上下文切换。 这为您提供了在bakcground中运行长时间运行任务的绝佳机会,之后在UI线程上执行了UI引用任务。

如果您使用的是.Net 4.0,则可以像这样使用Parallel.Invoke方法

 Parallel.Invoke(()=> { // What ever code you add here will get threaded. }); 

有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/dd992634.aspx

如果您的原始代码或转换后的代码没有完全使用CPU,您会看到不同。 也就是说,如果原始代码总是将线程数限制为2,那么在四核机器上,它将以大约50%的负载运行,并且可以手动创建线程,并且可能100%加载任务(如果您的任务可以被动作分段)。 因此,从性能的角度来看,您的原始代码看起来是合理的,或者两种实现方式都会遇到类似CPU未充分利用的问题。