“等待”不等待电话完成

时间:2012-09-02 12:31:08

标签: c# asynchronous .net-4.5

我正在构建Metro App。

在MainPage.xaml.cs中,我按如下方式实例化Album:

Album album = new Album(2012);  //With the album ID as its parameter.
ListView1.ItemsSource = album.Songs;

在Album.cs中,构造函数如下:

public Album(int ID)
{
    this.ID = ID;
    Initialize();  //Serves as a wrapper because I have to call httpClient.GetStreamAsync() and "async" doesn't work for the constructor.
}

最后,Initialize方法:

private async void Initialize()
{
    //...some code...
    HttpClient cli = new HttpClient();
    Stream SourceStream = await HttpClient.GetStreamAsync("http://contoso.com");
    //...some code...
    this.Songs = Parse(SourceStream);
}

问题是当它运行到GetStreamAsync时,它会直接转到ListView1.ItemsSource = album.Songs album.Songs null。

这个问题有什么快速解决方案吗? Thx提前。

2 个答案:

答案 0 :(得分:34)

是。 asyncawait的重点是阻止。相反,如果您正在“等待”尚未完成的操作,则会计划继续执行其余的异步方法,并将控制权返回给调用者。

现在因为你的方法的类型为void,你无法知道它何时完成 - 如果你返回Task(这不需要对方法体进行任何改动)你完成时至少可以锻炼身体。

您的代码看起来并不是很清楚,但从根本上说,您应该只在初始化完成后尝试设置ItemsSource 。您也应该在异步方法中使用MainPage代码,这看起来像:

Album album = new Album(2012);
ListView1.ItemsSource = await album.GetSongsAsync();

您的GetSongs()电话会是:

private async Task<List<Song>> GetSongsAsync()
{
    //...some code...
    HttpClient cli = new HttpClient();
    Stream SourceStream = await HttpClient.GetStreamAsync("http://contoso.com");
    //...some code...
    return Parse(SourceStream);
}

这意味着Songs将不再是Album本身的属性,但如果您愿意,可以将其添加到缓存中。

答案 1 :(得分:5)

Songs属性返回Task<List<Song>>并等待ListView1.ItemsSource = await album.Songs;