我可以从Task <observablecollection <class>&gt;进行转换吗?到ObservableCollection <class>?

时间:2017-05-30 21:07:56

标签: c# uwp async-await

我有一个有效的Async方法(web scrape),但无法更新View。 我可以看到INotifyPropertyChanged事件没有触发。

在我的构造函数中,我像这样调用异步方法:

Task<ObservableCollection<Team>> TeamRows2 = Scrape();

我的Scrape方法返回:

ObservableCollection<Team> rows 

通过这种方法签名:

private async Task<ObservableCollection<Team>> Scrape()
ObservableCollection<Team> rows = new ObservableCollection<Team>();
// do Async work
return rows;

我可以看到行填充了Async web获取的数据。

但是Scrape的调用似乎并没有在返回时为行加载TeamRows2。

我是否需要以某种方式从任务的普通ObservableCollection进行转换才能工作?

由于

1 个答案:

答案 0 :(得分:0)

正如评论已经建议你需要等待任务完成。有一种方法可以调用Task.Result,但是有一些常见的情况是调用此方法会导致应用程序出现死锁,一切都会停止。

作为一般规则,您可以说:切勿将async/await.Result/.Wait混合使用。

现在您的主要问题是您在构造函数内部工作,需要等待您的任务完成。我更喜欢这个问题的解决方案是静态工厂方法。

像这样:

public static async Task<YourClass> CreateAsync(…)
{
   var rows = await Scrape();
   return new YourClass(rows, …);
}

构造函数设置为private,当您需要创建类的实例时,可以调用CreateAsync方法。

此解决方案假定Scrape方法也是静态的。但是无论如何你应该从构造函数中调用它(或者至少它应该很容易使它static,因为它可以接收的所有参数都必须传递给构造函数。

另一种解决方案是使用初始化函数。如果您无法将Scape方法设置为静态,那么这将是解决方案。即使在这种情况下,我也建议使用工厂方法,以避免暴露未正确初始化的类的实例。

在这种情况下,您基本上需要两种方法:

public static async Task<YourClass> CreateAsync(…)
{
   var result = new YourClass(…);
   await result.InitializeAsync();
   return result;
}

private async Task InitializeAsync()
{
   TeamRows2 = await Scrape();
}