从 WPF 视图模型中的属性设置器调用异步方法是错误的吗? [英] Is wrong to invoke an async method from property setter in WPF view model?

查看:17
本文介绍了从 WPF 视图模型中的属性设置器调用异步方法是错误的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When a property changes its value I want to call an async method that fetches data from a web service an then updates another property to which the UI is bound causing the UI to update. It makes sense to me that the update is async as I want the UI to remain responsive while the update is going on.

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

Is it wrong to call an async method from the non async setter? I noticed that if the async method return void then VS does not complain but if it returns Task then visual studio complains that the call is not awaited. My code looks like this:

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
}

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

It seems to work but I wonder if I am not using async the way it was intended given the warning I get from VS if the return type is Task.

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

UPDATE: Several answers and comments have suggest the user of commands rather than updating in response to a change in a property. For my case I am not sure how that could be applied so am providing more details about how the UI is expected to work.

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

In the user interface there is date picker (which is bound to the property in question on the view model) where the user selects the date for which he wants to view records. When a new date is selected by the user, the app should show a busy indicator, and then fetch records in the background to avoid blocking the UI thread. Preferably I want the update to be initiated when the date selected, without requiring the user to push a button after the date is selected.

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

Would it be better to bind the SelectionChanged event of the date picker to and async command on the ViewModel or alternatively have an sync handler for the SelectionChanged which calls the update method on the view model directly?

推荐答案

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

Is it wrong to call an async method from the non async setter?

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

In short, yes. Properties should not not be kicking off asynchronous background operations in their setters.

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

I recommend you to read Stephen Cleary's blog post and MSDN article on the subject:

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

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

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

You may also want to look into a functional MVVM framework such as ReactiveUI that handles this scenario by converting properties into observable streams of values that you can subscribe to: https://reactiveui.net/docs/getting-started/

这篇关于从 WPF 视图模型中的属性设置器调用异步方法是错误的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆