#c_sharp #xamarin #async_await
This question already has an answer here: Зависает оператор `await` в оконном приложении / программа висит при вызове Task.Result или Wait (1 ответ) Закрыт 1 год назад. Пытаюсь разобраться с async/await. Вызываю асинхронный метод: public static async Task GetData(string url) { dynamic results = await DataService.getData(url); } Cам метод: public static async TaskgetData(string url) { HttpClient client = new HttpClient(); var response = await client.GetAsync(url); while(true){} // специально сделанное зацикливание, чтобы увидеть что UI не блокируется dynamic data = null; if(response !=null) { string json = response.Content.ReadAsStringAsync().Result; data = JsonConvert.DeserializeObject(json); } return data; } Однако при вызове этого метода всё зависает. Почему все зависает, ведь на сколько я понимаю, async\await должен создаваться в отдельном потоке и следовательно не должен блочить UI, а просто зацикливаться в "фоновом" потоке?
Ответы
Ответ 1
Нет, вы понимаете неправильно. Если async-функция запущена в UI-потоке, она в нём и выполняется (это можно легко увидеть, залогировав Id потока), за исключением await’ов, во время которых функция вообще нигде не выполняется (и тем самым освобождает UI-поток). Иначе как бы можно было получать доступ к UI-контролам в async-функции? Уберите вечный цикл, он завешивает UI. Что потенциально может вывести async-функцию в другой поток — это ConfigureAwait(false), но в вашей функции его нет. У вас ошибка в строке string json = response.Content.ReadAsStringAsync().Result; Вы не должны синхронно дожидаться завершения Task’а ReadAsStringAsync(). Замените это на string json = await response.Content.ReadAsStringAsync(); Кстати, у вас есть ещё одна потенциально медленная операция в UI-потоке: JsonConvert.DeserializeObject(json). Вынесите её в фоновый поток при помощи data = await Task.Run(() => JsonConvert.DeserializeObject(json)); По поводу механики (как именно работает async-функция на нижнем уровне) можно почитать, например, тут, тут, тут, тут, тут и тут. И посмотреть тут.
Комментариев нет:
Отправить комментарий