我想知道在.NET应用程序中(确切地说,在ViewModel中),执行主线程任务的最佳异步方式是什么。Dispatcher.BeginInvoke现在是否仍然有效,或者有更好的方法来实现这一点?
我想知道在.NET应用程序中(确切地说,在ViewModel中),执行主线程任务的最佳异步方式是什么。Dispatcher.BeginInvoke现在是否仍然有效,或者有更好的方法来实现这一点?
BeginInvoke
是一种非常底层的方法,通常情况下,您可以使用async
/await
从UI线程启动异步操作,并自动返回到UI线程显示结果。默认情况下,UI上下文由await
捕获并用于在等待的操作完成后恢复async
方法。(我在我的博客中更详细地描述了这个过程on my blog)。
如果您需要从UI中显示进度报告,则最佳选项是IProgress<T>
/Progress<T>
类型,它们也会为您执行所有线程处理的工作。
最后,如果您确实需要使用不断更新的数据来更新UI,则最佳选项是使用响应式扩展并在捕获的SynchronizationContext
上进行观察。
这些选项是从最常见到最不常见的。我估计90%的用例只需要async
/await
,99%的用例需要async
/await
+ IProgress<T>
,而100%的用例需要Rx。我从未遇到过需要使用BeginInvoke
的情况,即使使用它也没有好处。
BeginInvoke
仍然是正确的方法。await
/async
。请注意,如果正在执行的工作实际上不是异步的,并且只是将其包装在Task.Run
中,这仍然可能会阻塞UI线程。
await
抽象成一个“Fire and forget”方法,VM仍然有效地引入了线程。我认为你对涉及的交互的看法有点过于简单化,但我可能很容易错 :). - BradleyDotNET