1

我有几个执行自定义计算的计算器类。从历史上看,这些类的方法都是通过 BackgroundWorker 启动的,因为它们很长,运行时很明智。

最近我正在转换应用程序以使用 C# 中的新异步支持,现在通过 Task.Run() 运行相同的方法,但我注意到它们的运行速度慢了大约 5 - 7%(这对我来说很重要)应用)。

为什么线程池线程比 BackgroundWorker 正在做的任何事情都慢,是否有明显/预期的原因?

我没有对计算逻辑进行任何更改;我只是将计算方法传递给 Task.Run() (并等待它),在它被提供给 BackgroundWorker 之前,所以我很确定我自己没有引入任何导致速度降低的更改。

4

1 回答 1

3

如果您的计算过于细化,我希望看到这样的结果。

有一个开销Task.Run:首先,有必须导航的线程池队列;其次,执行上下文的编组(出于安全原因);第三,在捕获任何异常的操作周围有一个包装器。

如果您将单个BGW队列与自己的队列一起使用,那么您的队列会更简单(并且可能更快)。执行上下文的编组只发生一次(对于整个BGW),并且每个操作都没有包装器(只有一个包装器BGW.DoWork)。

现在,如果您BGW每次计算都使用一个,那么我希望Task.Run会更快。

作为替代方案,请查看任务并行库。对于计算,我建议使用Parallel类型(或 PLINQ),Task.Run除非您确实需要动态并行性。如果您想了解更多信息,请阅读Parallel Programming with Microsoft .NET,尤其是这张图片(但请注意,“Futures”最好用async/表示await,“Pipelines”最好用 TPL 数据流表示)。

于 2013-05-21T14:45:17.457 回答