Асинхронное выполнение http запросов
Есть у меня синхронный http запрос, и он прекрасно работает:
private string zaproshttp(string sURL)
{
WebRequest wrGETURL = WebRequest.Create(sURL);
Stream objStream = null;
try
{
objStream = wrGETURL.GetResponse().GetResponseStream();
}
catch
{
Обработка ошибок...
}
StreamReader objReader = new StreamReader(objStream);
return objReader.ReadLine());
}
Но тут возникает проблема, иногда ответ от сервера долго не приходит, и программа подвисает. В принципе ничего страшного в этом нет, без ответа сервера смысла в работе программы нет. Но пользователи часто не дожидаются ответа, т.к. думают, что программа зависла. В голову пришла идея, сделать http запрос асинхронным, а в основном пакете крутить Гифку, типа ждите... (в синхронном режиме программа висит и гифка не крутится). Вот код подсмотренный в просторах тырнета:
private async Task<string> zaproshttp2(string sURL )
{
HttpWebRequest request = WebRequest.CreateHttp(sURL);
request.Method = "GET";
using (HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
return reader.ReadLine();
}
}
}
И этот код наглухо зависает на using (HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
Как я понимаю, запрос выполняется, но код дальше не работает. Пробовал через другие способы, так же зависает. В чем проблема, куда копать?
Ответы (1 шт):
код наглухо зависает - это верятно дедлок и вам надо было вместо return reader.ReadLine(); делать return await reader.ReadLineAsync(); хотя в данном случае наверное всё-таки reader.ReadToEndAsync().
WebRequest устарел очень давно, используйте HttpClient, он сам по себе асинхронный.
// HttpClient создается один раз на всё время работы приложения
private static readonly HttpClient client = new HttpClient();
private async Task<string> HttpRequest(string url)
{
try
{
return await client.GetStringAsync(url).ConfigureAwait(false);
}
catch (Exception ex)
{
// ex.Message
}
return null;
}
Если нужно вернуть ответ даже если сервер ответил ошибкой (код выше бросит исключение), то можно написать так:
private async Task<string> HttpRequest(string url)
{
try
{
using (HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false))
{
return await response.ReadAsStringAsync();
}
}
catch (Exception ex)
{
// ex.Message
}
return null;
}
В C# названия методов пишутся с большой буквы.
string responseText = await HttpRequest("https://example.ru");