I'm building a Metro App.
In the MainPage.xaml.cs, I instantiate Album as follows:
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:
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:
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.Songs
directly with the album.Songs null.
Is there any quick solution to this problem?
The answer at "await" doesn't wait for the completion of call has several, more detailed, explanations of these keywords. Show activity on this post. Show activity on this post. Show activity on this post.
Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.
await releases the current thread, but NOT to the thread pool. The UI thread doesn't come from the thread pool. If you run asynchronous method, e.g. ExecuteScalarAsync without async, await keywords, then this method will run asynchronously no matter what. The calling thread won't be affected .
An alternative way to wait for all promises to be done, you have to use async and await keywords, just add async keyword before function checkPhotos(... and ads await keyword before Promise. all... , that's will tell js engine that you need to run the code below await line when you got the response.
Yes. The whole point of async
and await
are that you don't block. 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.
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.
It's not really clear what your code looks like, but fundamentally you should only be trying to set the ItemsSource
after initialization has finished. You should probably have your MainPage
code in an async method too, which would look something like:
Album album = new Album(2012); ListView1.ItemsSource = await album.GetSongsAsync();
Your GetSongs()
call would then be:
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 Songs
would no longer be a property of Album
itself, although you could add it in for caching purposes if you wanted to.
Make Songs
property return Task<List<Song>>
and await at ListView1.ItemsSource = await album.Songs;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With