2012-03-27 10 views
68

У меня есть вызов, который я делаю из встроенного приложения на базе xaml, C# metro-приложения на Win8 CP; этот вызов просто удаляет веб-службу и возвращает данные JSON.Асинхронный вызов с ожиданием в HttpClient никогда не возвращается

HttpMessageHandler handler = new HttpClientHandler(); 

HttpClient httpClient = new HttpClient(handler); 
httpClient.BaseAddress = new Uri("http://192.168.1.101/api/"); 

var result = await httpClient.GetStreamAsync("weeklyplan"); 
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(WeeklyPlanData[])); 
return (WeeklyPlanData[])ser.ReadObject(result); 

Он висит на await но вызов HTTP фактически возвращает практически сразу (подтверждено через стельку); это как если бы await игнорируется, и он просто висит там.

Перед тем, как задать вопрос - ДА - включена функция Частной сети.

Любые идеи, почему это может повесить?

+1

Как вы называете этот метод 'async'? Разве это не исключение? – svick

ответ

97

Отметьте this answer на мой вопрос, который кажется очень похожим.

Что-то попробовать: позвоните ConfigureAwait(false) по заданию, возвращенной GetStreamAsync(). Например.

var result = await httpClient.GetStreamAsync("weeklyplan") 
          .ConfigureAwait(continueOnCapturedContext:false); 

ли это полезно, зависит от того, как ваш кода выше вызываются - в моем случае, вызывающем метод async с помощью Task.GetAwaiter().GetResult() вызвала код повесить.

Это потому, что GetResult() блокирует текущий поток, пока задача не завершится. Когда задача завершается, он пытается повторно ввести контекст потока, в котором он был запущен, но не может, потому что в этом контексте уже есть поток, который блокируется вызовом GetResult() ... тупик!

This MSDN post подробно рассказывает о том, как .NET синхронизирует параллельные потоки - и the answer given to my own question дает некоторые рекомендации.

+7

Спасибо, почти отказался от async/await, прежде чем увидеть это. – Den

+4

Я тоже! Почему этот материал не задокументирован? Еще раз спасибо –

+1

Это произойдет, если это не контекст пользовательского интерфейса и контекст ASP.NET? – machinarium