/ / "Waitit" wartet nicht auf den Abschluss des Aufrufs - c #, asynchron, .net-4.5

"Warten" wartet nicht auf die Beendigung des Aufrufs - c #, asynchron, .net-4.5

Ich baue eine Metro-App.

In der MainPage.xaml.cs instantiiere ich das Album wie folgt:

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

In der Album.cs sieht der Konstruktor folgendermaßen aus:

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

Zum Schluss noch die Initialize-Methode:

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

Das Problem ist, wenn es zu GetStreamAsync läuft, dann geht es direkt zu "ListView1.ItemsSource = album.Songs" mit dem album.Songs null.

Gibt es eine schnelle Lösung für dieses Problem? Danke im Voraus.

Antworten:

29 für die Antwort № 1

Ja. Der ganze Punkt von async und await bist du das nicht Block. Wenn Sie eine Operation, die noch nicht abgeschlossen ist, erneut "abwarten", ist eine Fortsetzung geplant, um den Rest der asynchronen Methode auszuführen, und die Steuerung wird an den Aufrufer zurückgegeben.

Nun, weil Ihre Methode einen Typ hat voidSie haben keine Möglichkeit zu wissen, wann das fertig ist - ob Sie zurückgekehrt sind Task (das würde keine Änderung im Körper der Methode erfordern) Sie können zumindest herausfinden, wann sie beendet ist.

Es ist nicht wirklich klar, wie Ihr Code aussieht, aber grundsätzlich sollten Sie nur versuchen, den Code festzulegen ItemsSource nach Die Initialisierung ist beendet. Sie sollten wahrscheinlich Ihre haben MainPage Code auch in einer asynchronen Methode, die ungefähr so ​​aussehen würde:

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

Ihre GetSongs() Aufruf wäre dann:

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

Das würde bedeuten Songs wäre nicht mehr Eigentum von Album selbst, obwohl Sie es für Zwischenspeicherzwecke hinzufügen könnten, wenn Sie wollten.


5 für die Antwort № 2

Machen Songs Eigentumsrückgabe Task<List<Song>> und warten auf ListView1.ItemsSource = await album.Songs;