Pour autant que je sache, il n'y a aucun moyen de savoir que c'est spécifiquement un délai d'expiration qui s'est produit. 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 renvoie:
Une ou plusieurs erreurs se sont produites.
Une tâche a été annulée.
c#
timeout
dotnet-httpclient
Benjol
la source
la source
Réponses:
Vous devez attendre la
GetAsync
méthode. Il lancera alors unTaskCanceledException
s'il a expiré. De plus,GetStringAsync
etGetStreamAsync
gèrent en interne le délai d'expiration, ils ne seront JAMAIS lancés.la source
GetStreamAsync
jeté unTaskCanceledException
pour moi.TaskCanceledException
est causé par un délai d'attente HTTP et non par une annulation directe ou une autre raison?TaskCanceledException.CancellationToken.IsCancellationRequested
. Si faux, vous pouvez être raisonnablement certain qu'il s'agissait d'un délai d'attente.IsCancellationRequested
le jeton d'exception lors de l'annulation directe comme je le pensais précédemment: stackoverflow.com/q/29319086/62600Je reproduis le même problème et c'est vraiment ennuyeux. J'ai trouvé cela utile:
HttpClient - gestion des exceptions agrégées
Le bogue dans HttpClient.GetAsync doit lever WebException, pas TaskCanceledException
Du code au cas où les liens ne vont nulle part:
la source
WebException
peut être attrapé. Cela aidera peut - être .default(CancellationToken)
avant de comparer avecex.CancellationToken
.J'ai trouvé que le meilleur moyen de déterminer si l'appel de service a expiré est d'utiliser un jeton d'annulation et non la propriété timeout de HttpClient:
Et puis gérez l'exception CancellationException pendant l'appel de service ...
Bien sûr, si le délai d'expiration se produit du côté du service, cela devrait pouvoir être géré par une WebException.
la source
cts.Token.IsCancellationRequested
esttrue
cela doit signifier qu'un délai d' attente est survenue?Depuis http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.timeout.aspx
Vous avez ensuite accès à la
Status
propriété, voir WebExceptionStatusla source
AggregateException
avec unTaskCancelledException
intérieur. Je dois faire quelque chose de mal ...catch(WebException e)
?AggregateException
n'est pas géré. Si vous créez un projet de console VS, ajoutez une référence àSystem.Net.Http
et déposez le code dansmain
, vous pouvez voir par vous-même (si vous le souhaitez).TaskCanceledException
. Cela semble être provoqué par la gestion du délai d'expiration interne du TPL, à un niveau supérieur auHttpWebClient
. Il ne semble pas y avoir de bon moyen de faire la distinction entre une annulation de timeout et une annulation d'utilisateur. Le résultat de ceci est que vous ne pouvez pas obtenir unWebException
dans votreAggregateException
.Fondamentalement, vous devez attraper
OperationCanceledException
et vérifier l'état du jeton d'annulation qui a été passé àSendAsync
(ouGetAsync
, ou quelle que soit laHttpClient
méthode que vous utilisez):IsCancellationRequested
est vrai), 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 timeout. Je propose ici une solution basée sur un gestionnaire de message HTTP personnalisé: Meilleure gestion du délai d'expiration avec HttpClientla source
HttpClient.Timeout
sur l'infini?est ce que je fais habituellement, semble fonctionner assez bien pour moi, c'est particulièrement bon lors de l'utilisation de proxies.
la source