Await / async无法按预期工作

我开始使用async / await了。 我使用基于MVVM模式的WPF编写了简单的应用程序,但它没有像我预期的那样工作。 该程序的工作原理是没有异步函数:执行执行函数后,只有在循环函数结束后才会冻结和解冻。

请告诉我哪些部分我弄错了。 我很感激任何反馈。 🙂

这是我的modelview类。 它inheritance自wpf类,它包含标准wpf函数的定义,如OnPropertyChanged。

public class ModelView : wpf { string _state; public string state { get { return _state; } set { _state = value; OnPropertyChanged("state"); } } public DelegateCommand work { get; set; } public ModelView() { state = "Program started"; work=new DelegateCommand(_work); } async void _work(object parameter) { state = "Working..."; int j=await loop(); state = "Done: " + j; } async Task loop() { int i; for(i=0;i<1000000000;i++); return i; } } 

代码中没有异步部分。 简单地使用async关键字并不是这样。 如果您希望将同步代码卸载到其他线程,请使用Task.Run

 async void _work(object parameter) { status = "Working..."; int j=await Task.Run(() => loop()); status = "Done: " + j; } int loop() { int i; for(i=0;i<1000000000;i++); return i; } 

如果您实际上有异步操作,则可以使用它:

 async void _work(object parameter) { status = "Working..."; await Task.Delay(1000); status = "Done: " + j; } 

准则:如果您的“异步”方法在其中没有await ,则它不是异步的。

你没有做任何异步。 async关键字并不意味着“创建另一个线程”; 它非常复杂,但基本上它允许代码另一个异步操作完成使用continuation。 好的例子包括异步数据库访问,文件访问,网络访问等。它还可以包括通过线程和Task.Run异步长时间运行操作。 但是: 你不是那样做的await没有什么不完整 – 代码只在主线程上运行 。 它只会在有不完整的东西继续进行安排继续

引用编译器(谈论loop方法):

警告此异步方法缺少’await’运算符并将同步运行。 考虑使用’await’运算符等待非阻塞API调用,或’await Task.Run(…)’在后台线程上执行CPU绑定工作。

看起来问题是你的loopfunction。 即使您已将其声明为async但它中没有await语句,您应该得到编译器警告,因为@Marc Gravell指出。

该函数通过大量循环迭代来旋转,这会占用阻塞的UI线程,然后返回最终值。

所以你的循环函数实际上是一个同步函数。 假设您为测试目的而这样做,模拟async操作的一个好方法是使用Task.Delay 。 例如:

 async Task loop() { await Task.Delay(5000); return 1; }