C# 等待/异步不';I don’我没有按预期工作
我正在开始使用async/await。我已经使用基于MVVM模式的WPF编写了一个简单的应用程序,但它并没有像我预期的那样工作。程序的工作原理是没有异步函数:在执行execute函数后,它只有在循环函数结束后才会冻结和解冻 请告诉我我弄错了什么地方。如有任何反馈,我将不胜感激。:) 这是我的modelview类。它继承自wpf类,该类包含标准wpf函数(如OnPropertyChanged)的定义C# 等待/异步不';I don’我没有按预期工作,c#,wpf,asynchronous,mvvm,async-await,C#,Wpf,Asynchronous,Mvvm,Async Await,我正在开始使用async/await。我已经使用基于MVVM模式的WPF编写了一个简单的应用程序,但它并没有像我预期的那样工作。程序的工作原理是没有异步函数:在执行execute函数后,它只有在循环函数结束后才会冻结和解冻 请告诉我我弄错了什么地方。如有任何反馈,我将不胜感激。:) 这是我的modelview类。它继承自wpf类,该类包含标准wpf函数(如OnPropertyChanged)的定义 public class ModelView : wpf { string _state;
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;
}
}
公共类模型视图:wpf
{
字符串状态;
公共字符串状态{get{return{u state;}set{u state=value;OnPropertyChanged(“state”);}
公共DelegateCommand工作{get;set;}
公共模型视图()
{
state=“程序已启动”;
work=新的DelegateCommand(_work);
}
异步无效工作(对象参数)
{
state=“Working…”;
int j=等待循环();
state=“Done:”+j;
}
异步任务循环()
{
int i;
对于(i=0;i您的代码中没有异步部分。简单地使用async
关键字是不行的。请使用Task。如果您希望将同步代码卸载到其他线程,请运行:
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”方法中没有await
,则它不是异步的。您没有做任何异步的事情。async
关键字并不意味着“创建另一个线程”;它相当复杂,但基本上它允许代码在另一个异步操作完成时继续工作。好的示例包括异步数据库访问、文件访问、网络访问等。它还可以包括通过线程和Task.Run
执行的异步长时间运行的操作。但是:您没有这样做It’wait
没有什么不完整的-代码只是在主线程上运行。它只在有不完整的内容需要继续时安排继续
引用编译器(谈论循环
方法):
警告此异步方法缺少“等待”操作符并将同步运行。考虑使用“Acess”操作符等待非阻塞API调用,或“等待任务.Run(…)”在后台线程上执行CPU绑定的工作。< /P>
问题似乎出在你的循环
函数上。尽管你已经声明它为异步
,但里面没有等待
语句,你应该得到一个编译器警告,正如@Marc Gravell所指出的
函数通过大量循环迭代旋转,占用UI线程,这将导致阻塞,然后返回最终值
因此,您的循环函数实际上是一个同步函数。假设您这样做是出于测试目的,那么模拟异步
操作的一个好方法是使用Task.Delay
例如:
async Task<int> loop()
{
await Task.Delay(5000);
return 1;
}
异步任务循环()
{
等待任务。延迟(5000);
返回1;
}
你几乎肯定会收到一个编译器警告,告诉你问题出在哪里。感谢你的回复,这是我所不知道的!@RicoW关键点:wait
从不创建线程;如果你正在等待的事情已经完成,它会继续进行;否则它会为“事情”添加一个延续,完成后,它将从那里运行continuation
async Task<int> loop()
{
await Task.Delay(5000);
return 1;
}