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

Best way to execute asynchronous task on main thread

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

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

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

BeginInvoke 很低级;总有更好的方法可用。

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

如果您需要显示来自 UI 的进度报告,最好的选择是 IProgress<T>/Progress<T> 类型,它再次为您进行所有线程编组。

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

这些选项从最常见到最不常见。我估计 90% 的用例仅包含 async/await,99% 包含 async/await + IProgress<T>,以及 100 % 被 Rx 覆盖。我从来没有 运行 遇到需要 BeginInvoke 的情况。甚至有益。