Отладчик останавливается после вызова async HttpClient.GetAsync() в visual studio
Я пытаюсь проверить метод http-запроса follwing
public async Task<HttpContent> Get(string url)
{
using (HttpClient client = new HttpClient())
// breakpoint
using (HttpResponseMessage response = await client.GetAsync(url))
// can't reach anything below this point
using (HttpContent content = response.Content)
{
return content;
}
}
Однако отладчик, похоже, пропускает код ниже второго комментария. Я использую Visual Studio 2015 RC, любые идеи? Я также попытался проверить окно "Задачи" и ничего не увидел
Изменить: найдено решение
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace ConsoleTests
{
class Program
{
static void Main(string[] args)
{
Program program = new Program();
var content = program.Get(@"http://www.google.com");
Console.WriteLine("Program finished");
}
public async Task<HttpContent> Get(string url)
{
using (HttpClient client = new HttpClient())
using (HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false))
using (HttpContent content = response.Content)
{
return content;
}
}
}
}
Оказывается, потому что это было консольное приложение на С#, оно закончилось после того, как я закончил основной поток, потому что после добавления Console.ReadLine() и ожидания бит возвращался запрос. Я догадался, что С# будет ждать, пока моя задача выполнится, а не закончится раньше, но я полагаю, что я ошибся. Если кто-нибудь сможет объяснить, почему это произошло, было бы хорошо.
Ответы
Ответ 1
Когда Main
завершается, программа завершает работу. Любые выдающиеся асинхронные операции отменены и их результаты отбрасываются.
Итак, вам нужно заблокировать Main
от выхода, либо заблокировав асинхронную операцию, либо какой-либо другой метод (например, вызывая Console.ReadKey
для блокировки до тех пор, пока пользователь не нажмет клавишу):
static void Main(string[] args)
{
Program program = new Program();
var content = program.Get(@"http://www.google.com").Wait();
Console.WriteLine("Program finished");
}
Один общий подход - определить MainAsync
, который выполняет обработку исключений:
static void Main(string[] args)
{
MainAsync().Wait();
}
static async Task MainAsync()
{
try
{
Program program = new Program();
var content = await program.Get(@"http://www.google.com");
Console.WriteLine("Program finished");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
Обратите внимание, что блокировка асинхронного кода обычно считается плохой идеей; очень мало случаев, когда это нужно сделать, а метод консольного приложения Main
просто один из них.