Soweit ich das beurteilen kann, gibt es keine Möglichkeit zu wissen, dass es sich speziell um eine Zeitüberschreitung handelt. Suche ich nicht am richtigen Ort oder vermisse ich etwas Größeres?
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);
}
Dies gibt zurück:
Ein oder mehrere Fehler sind aufgetreten.
Eine Aufgabe wurde abgebrochen.
c#
timeout
dotnet-httpclient
Benjol
quelle
quelle
Antworten:
Sie müssen die
GetAsync
Methode abwarten . Es wird dann ein geworfen,TaskCanceledException
wenn das Zeitlimit abgelaufen ist. ZusätzlichGetStringAsync
undGetStreamAsync
intern mit Timeout umgehen, damit sie NIEMALS werfen.quelle
GetStreamAsync
einTaskCanceledException
für mich geworfen.TaskCanceledException
durch ein HTTP-Timeout verursacht wird und nicht, beispielsweise durch direkte Stornierung oder einen anderen Grund?TaskCanceledException.CancellationToken.IsCancellationRequested
. Wenn dies falsch ist, können Sie ziemlich sicher sein, dass es sich um eine Zeitüberschreitung handelt.IsCancellationRequested
, bei der direkten Stornierung auf das Token der Ausnahme gesetzt zu werden, wie ich zuvor dachte: stackoverflow.com/q/29319086/62600Ich reproduziere das gleiche Problem und es ist wirklich ärgerlich. Ich habe diese nützlich gefunden:
HttpClient - Umgang mit aggregierten Ausnahmen
Ein Fehler in HttpClient.GetAsync sollte eine WebException auslösen, keine TaskCanceledException
Etwas Code für den Fall, dass die Links nirgendwo hingehen:
quelle
WebException
kann gefangen werden. Vielleicht dies helfen.default(CancellationToken)
vor dem Vergleich mitex.CancellationToken
.Ich habe festgestellt, dass der beste Weg, um festzustellen, ob das Zeitlimit für den Serviceabruf abgelaufen ist, die Verwendung eines Stornierungs-Tokens und nicht der Timeout-Eigenschaft des HttpClient ist:
Und dann die CancellationException während des Serviceabrufs behandeln ...
Wenn das Timeout auf der Serviceseite auftritt, sollte dies natürlich von einer WebException verarbeitet werden können.
quelle
cts.Token.IsCancellationRequested
isttrue
es muss bedeuten , dass ein Timeout aufgetreten ist?Von http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.timeout.aspx
Sie erhalten dann Zugriff auf die
Status
Eigenschaft, siehe WebExceptionStatusquelle
AggregateException
mit einemTaskCancelledException
Inneren zurück. Ich muss etwas falsch machen ...catch(WebException e)
?AggregateException
wird das nicht behandelt. Wenn Sie ein VS-Konsolenprojekt erstellen, einen Verweis aufSystem.Net.Http
den Code hinzufügen und ihn dort ablegenmain
, können Sie sich selbst davon überzeugen (wenn Sie möchten).TaskCanceledException
. Dies scheint durch die interne Timeout-Behandlung der TPL auf einer höheren Ebene als der ausgelöst zu werdenHttpWebClient
. Es scheint keine gute Möglichkeit zu geben, zwischen einer Timeout-Stornierung und einer Benutzer-Stornierung zu unterscheiden. Das Ergebnis davon ist, dass Sie möglicherweise keineWebException
in Ihrem bekommenAggregateException
.Grundsätzlich müssen Sie die fangen
OperationCanceledException
und prüfen Sie den Zustand des Widerrufs Token dass weitergegeben wurdeSendAsync
(oderGetAsync
, oder was auch immerHttpClient
Methode Sie verwenden):IsCancellationRequested
ist wahr), bedeutet dies, dass die Anfrage wirklich storniert wurdeNatürlich ist dies nicht sehr praktisch ... es wäre besser,
TimeoutException
im Falle einer Zeitüberschreitung eine zu erhalten . Ich schlage hier eine Lösung vor, die auf einem benutzerdefinierten HTTP-Nachrichtenhandler basiert: Bessere Timeout-Behandlung mit HttpClientquelle
HttpClient.Timeout
auf unendlich gesetzt?ist das, was ich normalerweise mache, scheint ziemlich gut für mich zu funktionieren, es ist besonders gut, wenn ich Proxys benutze.
quelle