На данный вопрос уже ответили:
Зависает оператор `await` в оконном приложении / программа висит при вызове Task.Result или Wait
1 ответ
Есть некоторое недопонимание с работой асинхронного кода, в связи с чем прошу помощи. Следующая функция вешает программу:
private List
Uri Uri = new Uri(Settings.CONTRACT_DETAIL_URI);
for (int i = 0; i < contracts.Length; i++) // По каждому контракту
{
HttpRequest ContractRequest = new HttpRequest(); //Это мой класс для работы с HttpClient
Dictionary
Task.WaitAll(requests); // Тут зависает программа
// Тут еще код, который я не дописал
return contractsList;
}
По информации в интернете не до конца понимаю:
работает ли WaitAll как await? И если да, то почему виснет
программа?
стартуют ли вообще мои Таски?
в каком месте кода я не прав? =)
Ответ
Нет. Task.Wait, Task.WaitAll - это совсем не await! await - это асинхронное продолжение, Wait же является синхронным ожиданием.
У вас взаимоблокировка. Вы работаете в потоке UI - а потому все ваши задачи свои продолжения ставят в очередь событий. Пока эта очередь не "провернется" - задача не будет выполнена. Но саму очередь вы при этом заблокировали синхронным ожиданием!
Правильный способ избавиться от взаимоблокировки - использовать асинхронный код на всех уровнях. Да, для этого саму функцию GetContractsDetail нужно тоже сделать асинхронной:
await Task.WhenAll(requests);
Костыльный, но более простой способ - вынести задачи в пул потоков:
requests[i] = Task.Run(() => ContractRequest.Get(Uri, data));
Еще один костыльный и простой способ - проставить .ConfigureAwait(false) на первом операторе await в методе ContractRequest.Get
Комментариев нет:
Отправить комментарий