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? Thx in advance.
Make
Songs
property returnTask<List<Song>>
and await atListView1.ItemsSource = await album.Songs;
Yes. The whole point of
async
andawait
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 returnedTask
(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 yourMainPage
code in an async method too, which would look something like:Your
GetSongs()
call would then be:This means
Songs
would no longer be a property ofAlbum
itself, although you could add it in for caching purposes if you wanted to.