Отладчик останавливается после вызова 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 просто один из них.