我有一个有效的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进行转换才能工作?
由于
答案 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();
}