C# "await" 不等待调用完成
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12235967/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
"await" doesn't wait for the completion of call
提问by Isilm? O.
I'm building a Metro App.
我正在构建一个 Metro 应用程序。
In the MainPage.xaml.cs, I instantiate Album as follows:
在 MainPage.xaml.cs 中,我按如下方式实例化 Album:
Album album = new Album(2012); //With the album ID as its parameter.
ListView1.ItemsSource = album.Songs;
In the Album.cs, the constructor is as follows:
在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.
}
Finally, the Initialize method:
最后,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);
}
The problem is when it runs to GetStreamAsync, it then goes to ListView1.ItemsSource = album.Songsdirectly with the album.Songs null.
问题是当它运行到 GetStreamAsync 时,它然后ListView1.ItemsSource = album.Songs直接使用专辑.Songs null。
Is there any quick solution to this problem? Thx in advance.
有没有快速解决这个问题的方法?提前谢谢。
采纳答案by Jon Skeet
Yes. The whole point of asyncand awaitare that you don'tblock. Instead, if you're "awaiting" an operation which hasn't completed yet, a continuation is scheduled to execute the rest of the async method, and control is returned to the caller.
是的。整点async和await是你不阻止。相反,如果您正在“等待”一个尚未完成的操作,则将安排一个延续来执行异步方法的其余部分,并将控制权返回给调用者。
Now because your method has a type of void, you have no way of knowing when that's even finished - if you returned Task(which wouldn't require any change in the body of the method) you'd at least be able to work out when it had finished.
现在因为你的方法有一个 类型void,你无法知道它什么时候完成 - 如果你返回Task(这不需要对方法体进行任何更改)你至少可以在它何时完成已经结束。
It's not really clear what your code looks like, but fundamentally you should only be trying to set the ItemsSourceafterinitialization has finished. You should probably have your MainPagecode in an async method too, which would look something like:
不太清楚您的代码是什么样的,但从根本上说,您应该只ItemsSource在初始化完成后尝试设置。您可能也应该MainPage在异步方法中使用您的代码,它看起来像:
Album album = new Album(2012);
ListView1.ItemsSource = await album.GetSongsAsync();
Your GetSongs()call would then be:
您的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);
}
This means Songswould no longer be a property of Albumitself, although you could add it in for caching purposes if you wanted to.
这意味着Songs将不再是其Album自身的属性,尽管您可以根据需要将其添加到缓存中。
回答by L.B
Make Songsproperty return Task<List<Song>>and await at ListView1.ItemsSource = await album.Songs;
使Songs财产归还Task<List<Song>>并等待ListView1.ItemsSource = await album.Songs;

