处理异步get方法

本文关键字:方法 get 异步 处理 | 更新日期: 2023-09-27 18:16:40

我已经知道这是不可能的。我是c#和WP开发的新手,所以我只想学习最佳实践,如何处理这种情况的方法。下面是代码:

    public static ObservableCollection<Substance> Substances
    {
        get
        {
            if (_substances == null) await Substance.GetSubstanceDataAsync(); // and nothing gets returned anyway
                else return _substances;
        }
        set
        {
            _substances = value;
        }
    }

我应该在App.xaml.cs OnLaunched()方法中调用GetSubstanceDataAsync();,然后对存在的数据进行计数(抛出异常,如果它为null)?或者我应该让private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)方法在每个页面异步和检查空值每次页面导航到,如果是这样,获取数据(这可能是更好的解决方案)?

处理异步get方法

你知道,你的getter永远不能是异步的。因此,如果你需要一个只能通过异步方法获得的资源,getter显然不是正确的选择。

你可以做的是让你的属性是一个实例的ViewModel实现INotifyPropertyChanged。这样,当您的GetSubstanceDataAsync任务返回时,您可以通知侦听器您的Substance属性已经更改。非常方便的是,如果在XAML绑定中使用此属性,绑定将自动刷新。

private ObservableCollection<Substance> _substances;
public static ObservableCollection<Substance> Substances
{
    get
    {
        if (_substances == null) {
           GetSubstanceDataAsync();
        }
        return _substances;
    }
    set
    {
        _substances = value;
    }
}
private async void GetSubstanceDataAsync(){
    Substances = await Substance.GetSubstanceDataAsync();
}

现在,如果你在第一次调用列表时实现INotifyPropertyChanged并且它是空的,它将启动async方法。当async方法完成后,它将更新列表并通知UI有更新

有几种不同的可能方法,这取决于您实际想要做什么。

如果你想要真正的延迟初始化,那么你应该缓存Task<T>,也就是说,使用Lazy<Task<T>>(或者像我的AsyncEx库中的AsyncLazy<T>)。但是如果这是针对VM类的,那么延迟初始化就没有意义了(View 总是访问该属性)。

对于VM,您总是加载数据,因此您可以在构造函数中启动加载,并在数据到达时更新数据(通过INotifyPropertyChanged/INotifyCollectionChanged)。要记住的重要部分是,您还需要干净地处理异常。请注意,您的UI将(至少)有三种不同的状态:加载、成功和错误。当构造函数完成时,它将处于Loading状态,然后它将切换到Success或Error状态。

可以手工编写所有这些,或者您可以使用我在MSDN文章中关于异步MVVM数据绑定(也包括在我的AsyncEx库中)描述的NotifyTaskCompletion类型。NotifyTaskCompletion本质上只是一个Task<T>,它实现了INotifyPropertyChanged,所以当它完成(成功或错误)时,您可以通过数据绑定响应。