我有一个基于MVVM架构的WPF应用程序。我正在ViewModels上实现通用且广泛使用的INotifyPropertyChanged
接口,因为我需要对用户交互做出反应。
但是如何使用async void
'hacks'从同步的PropertyChanged事件处理程序中执行异步操作(例如,加载一些数据)?
谢谢!
编辑
我需要避免使用async void
的主要原因是因为我在测试驱动的环境中工作。异步void方法不可测试:(
答案 0 :(得分:2)
支持async void
的原因是允许在事件处理程序中使用await
,这些事件处理程序通常是无效的。
如果您希望它是可测试的,请用另一个async Task
方法编写整个代码,然后让事件处理程序直接调用它。在测试中测试此方法。
void OnPropertyChanged(PropertyChangedEventArgs e)
{
OnPropertyChangedAsync(e)
}
// Test this method
async Task OnPropertyChangedAsync(PropertyChangedEventArgs e)
{
...
}
答案 1 :(得分:1)
实际上,这与async void
无关。
通常,您要触发异步操作并让属性设置器返回。 示例代码段:
private string carManufacturerFilter;
public string СarManufacturerFilter
{
get { return carManufacturerFilter; }
set
{
if (carManufacturerFilter != value)
{
carManufacturerFilter = value;
OnPropertyChanged();
// fire async operation and forget about it here;
// you don't need it to complete right now;
var _ = RefreshCarsListAsync();
}
}
}
private async Task RefreshCarsListAsync()
{
// call some data service
var cars = await someDataService.GetCarsAsync(carManufacturerFilter)
.ConfigureAwait(false);
// ...
}
请注意,这里有很多要添加的内容:
P.S。我强烈建议您看看Reactive UI。
答案 2 :(得分:0)
不能。 INotifyPropertyChanged
不支持异步调用。您需要进行修改或重新考虑策略。
INotifyPropertyChanged
不适用于异步操作。其目标是使类能够通知UI其数据已更改。 UI在专用线程中工作,因此必须避免跨线程操作。
您应该使用“可怕的” async void
方法。
您也可以使用Dispatcher.BeingInvoke (async () => { … await …} )
,但与使用async void
相同。