在a similar question I asked recently中有一些很好的帮助,以及this SO answer中显示的类似示例之后,我尝试将其应用于MVVM视图模型中的命令,如下所示......
private async void BookAppointmentCommandExecute() {
Debug.WriteLine("VM Start");
IsBusy = true;
await Task.Run(() => Service.BookAppointment(Appointment.ID, PatientID));
IsBusy = false;
Debug.WriteLine("VM Done");
}
WCF服务调用如下所示......
[OperationContract]
public void BookAppointment(int appointmentID, int patientID) {
Debug.WriteLine("Svc Start");
Task.Delay(1000);
AppointmentsServiceLogic.BookAppointment(appointmentID, patientID);
Debug.WriteLine("Svc Done");
}
添加了Task.Delay
来模拟网络延迟,因此我可以检查视图上的忙指示是否正确显示。事实并非如此。
在这两种情况下,添加了Debug.WriteLine
语句以帮助我了解发生了什么。
与我链接的两个示例不同,我的代码不会在命令方法中的await
行暂停执行,而是立即执行。从“输出”窗口中的结果中,我可以看到Task.Delay
在命令方法执行完毕后发生的引起的延迟......
40:30:409 VM Start
40:30:409 Svc Start
40:30:409 VM Done
40:31:410 Svc Done
正如您所看到的,命令方法立即完成,然后有一秒钟的延迟(在IsBusy被设置回false之后),然后才返回服务方法。我认为这个想法是命令方法的执行被暂停,直到awaited
ed方法完成。
任何人都能解释我做错了什么?
答案 0 :(得分:1)
您似乎对async-await
的工作方式存在误解。查看Stephen Cleary的博客作为介绍:http://blog.stephencleary.com/2012/02/async-and-await.html
一些快速示例代码来说明您的问题:
Debug.WriteLine("Start");
await MyAsyncTask();
Debug.WriteLine("End");
await
关键字执行后面的任务(所以方法MyAsyncTask
)执行异步,但在继续执行之前等待它完成(这意味着"结束"是MyAsyncTask
完成优惠后打印到控制台
另一个例子:
Debug.WriteLine("Start");
MyAsyncTask();
Debug.WriteLine("End");
现在"结束"在MyAsyncTask
启动后立即写入控制台,因此在完成之前。
应用于您的具体示例我说要做到这一点的方法是
private async void BookAppointmentCommandExecute() {
Debug.WriteLine("VM Start");
IsBusy = true;
await Service.BookAppointment(Appointment.ID, PatientID); //as I've changed the return type of the method below, I can now directly await it
IsBusy = false;
Debug.WriteLine("VM Done");
}
//the method should return Task, so you can use the await keyword to wait for its completion
//I've marked the method with the async keyword so I can use the await keyword within
[OperationContract]
public async Task BookAppointment(int appointmentID, int patientID) {
Debug.WriteLine("Svc Start");
await Task.Delay(1000);
//(depending if AppointmentsServiceLogic.BookAppointment is implemented asynchronous)
await AppointmentsServiceLogic.BookAppointment(appointmentID, patientID);
//or
await Task.Run(() => AppointmentsServiceLogic.BookAppointment(appointmentID, patientID));
Debug.WriteLine("Svc Done");
}