2012-03-27 18 views
68

Tengo una llamada que hago desde dentro de una aplicación de metro C# basada en xaml en el CP Win8; esta llamada simplemente golpea un servicio web y devuelve datos JSON.Llamada asíncrona con espera en HttpClient nunca devuelve

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); 

Se cuelga en el await pero la llamada http realidad vuelve casi inmediatamente (confirmado por el violinista); es como si el await se ignora y simplemente se cuelga allí.

Antes de preguntar - SÍ - la función de red privada está activada.

¿Alguna idea de por qué esto se bloquea?

+1

¿Cómo llamas a ese método 'async'? ¿No arroja una excepción? – svick

Respuesta

97

Consulte this answer a mi pregunta que parece ser muy similar.

Algo que probar: llame al ConfigureAwait(false) en la tarea devuelta por GetStreamAsync(). P.ej.

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

Sea o no esto es útil depende de la forma en que su código está siendo llamado - en mi caso llamando al método async usando Task.GetAwaiter().GetResult() causó el código para colgar.

Esto se debe a que GetResult() bloquea la secuencia actual hasta que la tarea finaliza. Cuando la tarea se completa, intenta volver a ingresar al contexto del hilo en el que se inició, pero no puede porque ya hay un hilo en ese contexto, que está bloqueado por la llamada al GetResult() ... interbloqueo!

This MSDN post entra en detalles sobre cómo .NET sincroniza los hilos paralelos, y the answer given to my own question brinda algunas de las mejores prácticas.

+7

Gracias, casi me rindo por async/await antes de ver esto. – Den

+4

¡Yo también! ¿Por qué no está esto mejor documentado? Gracias de nuevo –

+1

¿Va a suceder si está en el contexto de la interfaz de usuario y en el contexto de ASP.NET? – machinarium

Cuestiones relacionadas