实际上,数据绑定需要INotifyPropertyChanged.PropertyChanged
在 UI 同步上下文中引发。
async
/await
确实强制您区分属性(表示当前状态并且始终是同步的)和命令(表示动作并且可能是同步的或异步的)。属性 getter 和 setter不能,async
因此您的示例代码带有“异步集”是不可能的方法。
async
启用异步命令。您可以使用命令绑定来异步处理路由命令,或将async
委托传递给 a DelegateCommand
,或使用您自己的ICommand
实现。无论您采用哪种方式,最终都会得到一个async void
命令事件处理程序。
一个现实的例子是让 VM 属性在内存中设置 M 属性,并SaveCommand
使用一个async
处理程序。让async
处理程序与额外的 VM 属性(SaveInProgress
或者可能Busy
与其他async
处理程序共享的公共属性)交互是很常见的,这样 UI 可以在命令进行时做出适当的响应(通常至少会导致CanExecute
返回false
)。
所以你的async
处理程序最终看起来像:
private async void SaveCommandExecute()
{
try
{
// Set VM property; updates View appropriately.
Busy = true;
// Do the actual saving asynchronously.
await Model.SaveAsync();
}
catch (Exception ex)
{
// Update the VM with error information.
Error = ex.Message;
}
finally
{
// Let the VM know we're done.
Busy = false;
}
}
private void SaveCommandCanExecute()
{
return !Busy;
}
请注意,VM 属性 (Error
和Busy
) 在捕获的 UI 同步上下文中更新。
这说明了async
MVVM 的中心概念:命令可能是async
,但属性(例如Busy
)始终代表当前状态。
如果您要添加async
到现有的 MVVM 应用程序,您会发现自己具有几个指示业务的附加属性,并且可能还有进度更新(例如,完成百分比)。根据您的应用程序,您可以同时允许多个异步操作。您需要考虑将这些信息添加到您的视图中的好方法;我发现这是async
MVVM 应用程序中最具挑战性的部分。