我开始使用async / await。我使用基于MVVM模式的WPF编写了简单的应用程序,但它并没有像我预期的那样工作。该程序的工作原理是没有异步函数:执行执行函数后,只有在循环函数结束后才会冻结和解冻。
请告诉我哪些部分我弄错了。我很感激任何反馈。 :)
这是我的modelview类。它继承自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<int> loop()
{
int i;
for(i=0;i<1000000000;i++);
return i;
}
}
答案 0 :(得分:10)
代码中没有异步部分。仅使用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;
}
指南:如果您的&#34; async&#34;方法里面没有await
,它不是异步的。
答案 1 :(得分:5)
你没有做任何异步的事情。 async
关键字并不意味着&#34;创建另一个线程&#34 ;;它非常复杂,但基本上它允许代码在另一个异步操作完成时使用continuation 。好的例子包括异步数据库访问,文件访问,网络访问等。它还可以包括通过线程和Task.Run
的异步长时间运行操作。但是:你不是那样做的。 await
没有任何不完整的内容 - 代码只是在主线程上运行。它只会在有一些不完整的内容时安排继续。
引用编译器(谈论loop
方法):
警告此异步方法缺少等待&#39;运营商并将同步运行。考虑使用&#39; await&#39;运营商等待非阻塞API调用,或等待Task.Run(...)&#39;在后台线程上进行CPU绑定工作。
答案 2 :(得分:1)
看起来问题是你的loop
功能。即使您已将其声明为async
,但其中没有await
语句,您应该收到编译器警告,因为@Marc Gravell指出。
该函数通过大量循环迭代来旋转,这会占用阻塞的UI线程,然后返回最终值。
所以你的循环函数实际上是一个同步函数。假设您为测试目的而这样做,模拟async
操作的一个好方法是使用Task.Delay
。例如:
async Task<int> loop()
{
await Task.Delay(5000);
return 1;
}