在主线程上执行异步任务的最佳方法

时间:2015-05-04 22:06:53

标签: c# .net wpf asynchronous async-await

我想知道在.NET应用程序的主线程上执行任务的最佳异步方式是什么(准确地说是在ViewModel中)。 Dispatcher.BeginInvoke现在仍然有效还是存在更好的方法呢?

2 个答案:

答案 0 :(得分:7)

BeginInvoke非常低级别;总是有更好的方法。

在大多数情况下,您可以使用async / await从UI线程启动异步操作,并自动返回UI线程以显示结果。默认情况下,UI上下文由await捕获,用于在等待操作完成后恢复async方法。 (我更详细地描述了这一点on my blog)。

如果您需要从用户界面显示进度报告,最好的选项是IProgress<T> / Progress<T>类型,它们会再次为您执行所有线程编组。

最后,如果您确实需要使用无休止的数据序列更新UI,最好的选择是使用Reactive Extensions并观察捕获的SynchronizationContext

这些选项从最常见到最不常见。我估计只有async / await覆盖了90%的用例,99%覆盖了async / await + IProgress<T>,并且100%覆盖Rx。我从未遇到过需要BeginInvoke的情况。甚至是有益的。

答案 1 :(得分:3)

如果您需要将操作编组到UI线程上,是的,BeginInvoke 仍然是正确的方法。

如果您已经的UI线程中,但又不希望您的操作被阻止,则可以使用await / async。请注意,如果正在完成的工作实际上并非异步,并且您只是将其包装在Task.Run中,则仍然会阻止您的UI线程。