HttpClient.PostAsync выбивает приложение с кодом выхода 0

Сегодня все работало, пока не остановилось... Ниже приведен минимальный исходный код (я использую VS 2012 Update 1, .Net 4.5). Когда я запускаю его, приложение закрывается при вызове client.PostAsync() и поэтому никогда не достигает Console.ReadLine(). То же самое в отладчике, никаких исключений, ничего, код выхода 0.

Я пробовал перезагружать машину, перезапускать VS2012 - ничего не работает.

Опять же, сегодня все работало, не знаю, что изменилось (программное обеспечение не было установлено и т. Д., Все другие сетевые приложения все еще работают).

Любые идеи? Я думаю, что теряю рассудок.

class Program
{
    static void Main(string[] args)
    {
        Run();
    }

    private async static void Run()
    {
        using (var client = new System.Net.Http.HttpClient())
        {
            var headers = new List<KeyValuePair<string, string>>
                              {
                                  new KeyValuePair<string, string>("submit.x", "48"),
                                  new KeyValuePair<string, string>("submit.y", "15"),
                                  new KeyValuePair<string, string>("submit", "login")
                              };

            var content = new FormUrlEncodedContent(headers);

            HttpResponseMessage response = await client.PostAsync("http://www.google.com/", content);

            Console.ReadLine();
        }
    }
}

person Maxim    schedule 06.01.2013    source источник


Ответы (1)


Ваша проблема в том, что программа обычно завершает работу, когда завершается ее метод Main(). И ваш Main() завершится, как только вы нажмете await в Run(), потому что так работают методы async.

Что вам нужно сделать, так это превратить Run() в метод async Task, а затем дождаться Task в вашем методе Main():

static void Main()
{
    RunAsync().Wait();
}

private static async Task RunAsync()
{
    …
}

В С# 7.1+ вместо этого следует использовать async Main:

static async Task Main()
{
    await RunAsync();
}

private static async Task RunAsync()
{
    …
}

Еще несколько заметок:

  1. Вы никогда не должны использовать методы async void, за исключением случаев, когда это необходимо (как в случае с асинхронными обработчиками событий).
  2. Смешивание await и Wait() в приложении с графическим интерфейсом или в ASP.NET опасно, поскольку приводит к взаимоблокировкам. Но это правильное решение, если вы хотите использовать async в консольном приложении.
person svick    schedule 06.01.2013
comment
+1. В качестве подсказки проще выполнить try/catch верхнего уровня в RunAsync, а не Main, потому что Task.Wait перенесет исключения в AggregateException. - person Stephen Cleary; 07.01.2013