Autant que je sache, il n’ya aucun moyen de savoir qu’il s’agit précisément d’un dépassement de délai. Est-ce que je ne cherche pas au bon endroit ou est-ce que je manque quelque chose de plus grand?
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);
}
Cela retourne:
Une ou plusieurs erreurs sont survenues.
Une tâche a été annulée.
Vous devez attendre la méthode GetAsync
. Il lancera alors un TaskCanceledException
s'il a expiré. De plus, GetStringAsync
et GetStreamAsync
gèrent en interne le délai d'attente, afin qu'ils ne jettent JAMAIS.
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);
}
Je reproduis le même problème et c'est vraiment énervant. J'ai trouvé cela utile:
HttpClient - traitant des exceptions globales
Quelques codes au cas où les liens ne vont nulle part:
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!?)
}
}
J'ai constaté que le meilleur moyen de déterminer si l'appel de service avait expiré est d'utiliser un jeton d'annulation et non la propriété de délai d'attente de HttpClient:
var cts = new CancellationTokenSource();
cts.CancelAfter(timeout);
Et puis gérer l'AnnulationException lors de l'appel de service ...
catch(TaskCanceledException)
{
if(!cts.Token.IsCancellationRequested)
{
// Timed Out
}
else
{
// Cancelled for some other reason
}
}
Bien sûr, si le délai d'attente se situe du côté du service, cela devrait pouvoir être géré par une exception WebException.
De http://msdn.Microsoft.com/en-us/library/system.net.http.httpclient.timeout.aspx
Une requête DNS (Domain Name System) (DNS) peut prendre jusqu'à 15 secondes pour revenir ou expirer. Si votre demande contient un nom d'hôte qui nécessite une résolution et que vous définissez Timeout sur une valeur inférieure à 15 secondes, 15 secondes ou plus peuvent s'écouler avant que une exception WebException soit générée pour indiquer un dépassement de délai sur votre demande. .
Vous aurez alors accès à la propriété Status
, voir WebExceptionStatus
En gros, vous devez attraper le OperationCanceledException
et vérifier l’état du jeton d’annulation qui a été passé à SendAsync
(ou GetAsync
, ou quelle que soit la méthode que vous utilisez HttpClient
utilisez):
IsCancellationRequested
est vraie), cela signifie que la demande a vraiment été annuléeBien sûr, ce n'est pas très pratique ... il serait préférable de recevoir un TimeoutException
en cas de dépassement du délai d'attente. Je propose ici une solution basée sur un gestionnaire de messages HTTP personnalisé: Meilleure gestion du délai d’attente avec HttpClient
_httpClient = new HttpClient(handler) {Timeout = TimeSpan.FromSeconds(5)};
c’est ce que je fais habituellement, semble bien marcher pour moi, c’est particulièrement bien quand on utilise des mandataires.