我正在重写MVVM框架的某些部分以使用async / await功能,请考虑以下VM代码:
private async Task LoadDossier(int ID)
{
//VM INotifyProperty
Dossiers = new ObservableCollection<Dossier>(await BubManager.GetAllBubDossiersForEmployeeByDossierIdAsync(ID).ConfigureAwait(false));
//VM INotifyProperty
SelectedDossier = Dossiers.First(x => x.Id == ID);
//VM INotifyProperty
DossierEmployer = await EmployerManager.GetEmployerByIdAsync(SelectedDossier.EmployerId).ConfigureAwait(false);
//VM INotifyProperty
DossierEmployee = await EmployeeManager.GetEmployeeByIdAsync(SelectedDossier.EmployeeId).ConfigureAwait(false);
//All VM INotifyProperties
if (SelectedDossier != null && DossierEmployer != null)
{
RszNr = DossierEmployer.RszNr;
FundsNr = DossierEmployer.FundsNr;
RrNr = DossierEmployee.RrNr;
}
RefreshGlobalCommanding();
}
由于我使用的是严格的MVVM,因此这里没有一个需要UI线程的属性,因此我在任何地方都使用ConfigureAwait(false)
。我知道在ObservableCollection
添加/删除时无法做到这一点,但这不是这种情况。
ConfigureAwait(false)
不一定有助于提高可读性IMO 修改
在与斯蒂芬讨论后,我得出结论,它基本上是一样的。
ConfigureAwait(false)
,你告诉WPF回调不必在UI线程上。设置INotifyProperty时,WPF会确保UI线程获得通知。两种情况都使WPF在某些时候进行UI线程编组。但是,我比较了两者的表现并且存在显着差异。我执行了一个循环1000次,其中一个对象绑定到一个视图,然后再次设置为null,这是以毫秒为单位的结果:
一个等待呼叫,任务延迟为10毫秒
ConfigureAwait(false)
三个等待任务延迟为10毫秒的呼叫
ConfigureAwait(false)
这个基准测试远非完美,但是似乎编组返回UI线程的属性比在同一个线程上运行await调用之后强制执行所有内容要便宜。这需要更多的测试来为所有场景提供明确的答案。
我只是把它放在这里,以证明两者之间存在差异。我的建议是在这种情况下不使用ConfigureAwait,因为它在更改代码时会增加异常的可能性,可读性较差,同事可能无法理解这一点,并且通过使用它来获得错误的安全感。
答案 0 :(得分:3)
这段代码是一个好习惯吗?
就个人而言,我选择将所有数据绑定属性视为具有UI亲和力。
一个原因是不同的MVVM框架在这方面具有不同的能力; WPF会为你处理这个问题(对于简单的属性),但其他人不会这样做。
如果是,那为什么不能将此作为默认行为?
当async
出现在CTP中时,有关await
的默认行为的讨论很多。各方都有利弊。