c# asynchronous .net-4.5

c# - "Esperar" no espera la finalización de la llamada



asynchronous .net-4.5 (2)

Estoy construyendo una aplicación de metro.

En MainPage.xaml.cs, instalo el Álbum de la siguiente manera:

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

En el Album.cs, el constructor es el siguiente:

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. }

Finalmente, el método de inicialización:

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

El problema es que cuando se ejecuta en GetStreamAsync, luego va a ListView1.ItemsSource = album.Songs directamente con el álbum.Songs null.

¿Hay alguna solución rápida a este problema? Gracias por adelantado.


Haga que las propiedades de las Songs devuelvan la Task<List<Song>> y esperen en ListView1.ItemsSource = await album.Songs;


Sí. Todo el punto de async y await es que no bloqueas. En cambio, si está "esperando" una operación que aún no se ha completado, se programa una continuación para ejecutar el resto del método asíncrono, y el control se devuelve a la persona que llama.

Ahora, debido a que su método tiene un tipo de void , no tiene forma de saber cuándo está terminado, si devolvió la Task (que no requeriría ningún cambio en el cuerpo del método) al menos podría trabajar cuando hubo terminado.

Realmente no está claro cómo se ve tu código, pero fundamentalmente solo deberías intentar configurar ItemsSource después de que la inicialización haya finalizado. Probablemente debería tener su código de MainPage en un método asíncrono, que se vería como:

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

Su llamada GetSongs() sería entonces:

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); }

Esto significa que las Songs ya no serían propiedad del propio Album , aunque podría agregarlo para propósitos de almacenamiento en caché si lo desea.