我正在重写MVVM框架的某些部分以利用异步/等待功能,请考虑以下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线程上并且没有问题。

  • 两种情况都使WPF在某些时候执行UI线程编码。但是,我将两者的性能进行了比较,并且存在显着差异。我执行了1000次循环,其中将对象绑定(bind)到 View ,然后再次设置为null,这是毫秒数的结果:

    一个等待调用,任务延迟为10毫秒

    ConfigureAwait(false)
  • 15623ms
  • 51700ms不带

  • 三个等待调用,任务延迟为10毫秒
  • 46917ms,带有ConfigureAwait(false)
  • 82647ms不带

  • 这个基准测试还远未达到完美,但是将属性编码回UI线程似乎比在等待调用后在所有线程上运行所有任务要便宜得多。但是,这需要更多的测试才能为所有情况给出确定的答案。

    我只是将其放在此处以证明两者之间存在差异。我的建议是在这种情况下不要使用ConfigureAwait,因为它增加了更改代码时出现异常的机会,可读性较差,并且同事可能不理解这一点,并因此而使用了错误的安全感。

    最佳答案



    我个人选择将所有数据绑定(bind)属性都视为具有UI亲和力。

    原因之一是不同的MVVM框架在这方面具有不同的功能。 WPF确实会为您处理此操作(针对简单属性),而其他人则不会。



    async放在CTP中时,关于await的默认行为进行了无数讨论。每种方式都有优点和缺点。

    关于c# - 严格的MVVM和Task.ConfigureAwait(false),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26236014/

    10-11 23:15