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

C# 在主线程上执行异步任务的最佳方法,c#,.net,wpf,asynchronous,async-await,C#,.net,Wpf,Asynchronous,Async Await,我想知道在.NET应用程序的主线程上执行任务的最佳异步方式是什么(确切地说是在ViewModel中)。Dispatcher.BeginInvoke现在仍然有效还是有更好的方法可以做到这一点?如果需要将操作封送到UI线程,是的,BeginInvoke仍然是正确的方法 如果您已经在UI线程上,但不想阻止您的操作,则可以使用wait/async。请注意,如果正在完成的工作实际上不是异步的,而您只是将其包装到一个任务中,那么这仍然会阻止您的UI线程。运行BeginInvoke是非常低级的;总有更好的方法

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

如果需要将操作封送到UI线程,是的,
BeginInvoke
仍然是正确的方法


如果您已经在UI线程上,但不想阻止您的操作,则可以使用
wait
/
async
。请注意,如果正在完成的工作实际上不是异步的,而您只是将其包装到一个
任务中,那么这仍然会阻止您的UI线程。运行
BeginInvoke
是非常低级的;总有更好的方法可用

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

如果您需要从UI显示进度报告,最好的选择是
IProgress
/
progress
类型,它再次为您执行所有线程编组

最后,如果确实需要使用无休止的数据序列更新UI,最好的选择是使用反应式扩展,并在捕获的
同步上下文上观察


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

我很确定您不想在视图模型中引入多线程,可能是在使用异步。。。等等,好的。在视图模型中执行异步/等待有问题吗?在视图模型中执行线程(或者异步等待)没有问题。@garryp从模型加载数据怎么样?如果我的模型是一个WCF代理,也许它有一些值得期待的方法(实际上有这个方法)。即使您将
wait
抽象为一个“Fire-and-forget”方法,VM仍然有效地引入了线程。我认为您对所涉及的交互的看法有点过于简单,但我可能很容易出错:)。如果不深入到非常具体的示例,这是很困难的,但我认为模型不应该向相当高级别的视图模型公开此类信息。我猜你在想一个非常聪明的模型,而我更喜欢那些服务和助手封装了WCF服务调用之类的东西的模型。回答得很好。谢谢