/ / "Очікувати" не чекає завершення виклику - c #, асинхронний, .net-4.5

“Await” не чекає завершення виклику - c #, асинхронний, .net-4.5

Я будую додаток метро.

У MainPage.xaml.cs я створюю альбом таким чином:

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

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

Нарешті, метод ініціалізації:

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

Проблема полягає в тому, що він запускається до GetStreamAsync, після чого переходить до "ListView1.ItemsSource = album.Songs" безпосередньо з альбомом.Songs null.

Чи є швидке вирішення цієї проблеми? Thx заздалегідь.

Відповіді:

29 для відповіді № 1

Так. Вся справа в async і await це ти не треба блок. Натомість, якщо ви "чекаєте" операції, яка ще не завершена, планується продовження виконання решти методу асинхронізації, а управління повертається до абонента.

Тепер тому, що ваш метод має тип void, ти не можеш знати, коли це ще закінчилося - якщо ти повернувся Task (що не вимагає будь-яких змін у складі методу), ви, принаймні, зможете розробити його після закінчення.

Це не зовсім зрозуміло, як виглядає ваш код, але в принципі вам слід лише намагатися встановити ItemsSource після ініціалізація закінчена. Ви, мабуть, повинні мати своє MainPage код у методі асинхронізації, який виглядатиме приблизно так:

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

Твій 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);
}

Це означає Songs більше не буде власністю Album сам, хоча ви можете додати його в цілях кешування, якщо цього хочете.


5 для відповіді № 2

Зробити Songs повернення майна Task<List<Song>> і чекаємо на ListView1.ItemsSource = await album.Songs;