#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 Task getData(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-функция на нижнем уровне) можно почитать, например, тут, тут, тут, тут, тут и тут. И посмотреть тут.
Комментариев нет:
Отправить комментарий