从 WPF 视图模型中的属性设置器调用异步方法是错误的吗?

Sha*_*ane 3 c# wpf task-parallel-library

当属性更改其值时,我想调用从 Web 服务获取数据的异步方法,然后更新 UI 绑定到的另一个属性,从而导致 UI 更新。更新是异步的对我来说很有意义,因为我希望 UI 在更新进行时保持响应。

从非异步 setter 调用异步方法是错误的吗?我注意到如果异步方法返回 void 则 VS 不会抱怨,但如果它返回 Task 则 Visual Studio 会抱怨没有等待调用。我的代码如下所示:

public int Property1
{
    set 
    {
        _property1 = value;
        NotityPropertyChanged();
        UpdateData();
    }
}

private async void UpdateData()
{
    // show data loading message
    var data = await GetDataFromWebService();
    Property2 = data;
    // hide data loading message
}
Run Code Online (Sandbox Code Playgroud)

它似乎有效,但我想知道我是否没有按照预期的方式使用异步,因为如果返回类型是 Task,我会从 VS 收到警告。

更新:一些答案和评论建议用户使用命令而不是更新以响应属性的变化。对于我的情况,我不确定如何应用它,因此我提供了有关 UI 预期如何工作的更多详细信息。

在用户界面中有日期选择器(它绑定到视图模型上的相关属性),用户可以在其中选择他想要查看记录的日期。当用户选择新日期时,应用程序应显示忙指示符,然后在后台获取记录以避免阻塞 UI 线程。最好我希望在选择日期时启动更新,而不需要用户在选择日期后按下按钮。

将日期选择器的 SelectionChanged 事件绑定到 ViewModel 上的异步命令,或者为 SelectionChanged 设置一个同步处理程序,它直接调用视图模型上的更新方法会更好吗?

mm8*_*mm8 5

从非异步 setter 调用异步方法是错误的吗?

简而言之,是的。属性不应在其 setter 中启动异步后台操作。

我建议您阅读有关该主题的 Stephen Cleary 的博客文章和 MSDN 文章:

异步编程:异步 MVVM 应用程序模式:数据绑定: https : //msdn.microsoft.com/en-us/magazine/dn605875.aspx

异步 OOP 3:属性: https : //blog.stephencleary.com/2013/01/async-oop-3-properties.html

您可能还想研究一个功能性 MVVM 框架,例如通过将属性转换为您可以订阅的可观察值流来处理这种情况的ReactiveUIhttps : //reactiveui.net/docs/getting-started/