处理异步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)
方法在每个页面异步和检查空值每次页面导航到,如果是这样,获取数据(这可能是更好的解决方案)?
你知道,你的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
,所以当它完成(成功或错误)时,您可以通过数据绑定响应。