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