c# timeout dotnet-httpclient

c# - ¿Cómo puedo saber cuándo se ha agotado el tiempo de HttpClient?



httpclient timeout angular (5)

Básicamente, debe atrapar la OperationCanceledException y verificar el estado del token de cancelación que se pasó a SendAsync (o GetAsync , o el método HttpClient que esté utilizando):

  • si fue cancelado ( IsCancellationRequested es verdadero), significa que la solicitud realmente fue cancelada
  • si no, significa que la solicitud ha excedido el tiempo de espera

Por supuesto, esto no es muy conveniente ... sería mejor recibir una TimeoutException en caso de tiempo de espera. Aquí propongo una solución basada en un manejador de mensajes HTTP personalizado: mejor manejo del tiempo de espera con HttpClient

Por lo que puedo decir, no hay forma de saber que es específicamente un tiempo de espera que ha ocurrido. ¿No estoy mirando en el lugar correcto, o me estoy perdiendo algo más grande?

string baseAddress = "http://localhost:8080/"; var client = new HttpClient() { BaseAddress = new Uri(baseAddress), Timeout = TimeSpan.FromMilliseconds(1) }; try { var s = client.GetAsync("").Result; } catch(Exception e) { Console.WriteLine(e.Message); Console.WriteLine(e.InnerException.Message); }

Esto devuelve:

Uno o más errores ocurrieron.

Una tarea fue cancelada.


Descubrí que la mejor manera de determinar si la llamada de servicio ha expirado es utilizar un token de cancelación y no la propiedad de tiempo de espera de HttpClient:

var cts = new CancellationTokenSource(); cts.CancelAfter(timeout);

Y luego maneje la CancellationException durante la llamada de servicio ...

catch(TaskCanceledException) { if(!cts.Token.IsCancellationRequested) { // Timed Out } else { // Cancelled for some other reason } }

Por supuesto, si el tiempo de espera se produce en el lado del servicio, eso debería ser manejado por una WebException.


Desde http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.timeout.aspx

Una consulta del Sistema de nombres de dominio (DNS) puede demorar hasta 15 segundos para regresar o expirar. Si su solicitud contiene un nombre de host que requiere resolución y establece Timeout en un valor de menos de 15 segundos, puede tomar 15 segundos o más antes de que se genere una WebException para indicar un tiempo de espera excedido en su solicitud .

A continuación, obtiene acceso a la propiedad Status , consulte WebExceptionStatus


Estoy reproduciendo el mismo problema y es realmente molesto. He encontrado estos útiles:

HttpClient: se trata de excepciones globales

El error en HttpClient.GetAsync debería arrojar WebException, no TaskCanceledException

Algún código en caso de que los enlaces no lleguen a ninguna parte:

var c = new HttpClient(); c.Timeout = TimeSpan.FromMilliseconds(10); var cts = new CancellationTokenSource(); try { var x = await c.GetAsync("http://linqpad.net", cts.Token); } catch(WebException ex) { // handle web exception } catch(TaskCanceledException ex) { if(ex.CancellationToken == cts.Token) { // a real cancellation, triggered by the caller } else { // a web request timeout (possibly other things!?) } }


GetAsync esperar el método GetAsync . Luego lanzará una TaskCanceledException si se ha agotado el tiempo de espera. Además, GetStringAsync y GetStreamAsync manejan internamente el tiempo de espera, por lo que NUNCA lanzarán.

string baseAddress = "http://localhost:8080/"; var client = new HttpClient() { BaseAddress = new Uri(baseAddress), Timeout = TimeSpan.FromMilliseconds(1) }; try { var s = await client.GetAsync(); } catch(Exception e) { Console.WriteLine(e.Message); Console.WriteLine(e.InnerException.Message); }