O ile wiem, nie ma sposobu, aby dowiedzieć się, że nastąpił konkretny limit czasu. Czy nie szukam we właściwym miejscu, czy brakuje mi czegoś większego?
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);
}
To zwraca:
Wystąpił jeden lub więcej błędów.
Zadanie zostało anulowane.
c#
timeout
dotnet-httpclient
Benjol
źródło
źródło
Odpowiedzi:
Musisz poczekać na
GetAsync
metodę. Następnie wyrzuci,TaskCanceledException
jeśli upłynął limit czasu. DodatkowoGetStringAsync
iGetStreamAsync
wewnętrznie obsługują limit czasu, więc NIGDY nie będą rzucać.źródło
GetStreamAsync
wrzuciłemTaskCanceledException
dla mnie.TaskCanceledException
jest to spowodowane przekroczeniem limitu czasu HTTP, a nie, powiedzmy bezpośrednim anulowaniem lub innym powodem?TaskCanceledException.CancellationToken.IsCancellationRequested
. Jeśli fałszywe, możesz być dość pewny, że był to limit czasu.IsCancellationRequested
ustawienie na tokenie wyjątku przy bezpośrednim anulowaniu, jak wcześniej myślałem: stackoverflow.com/q/29319086/62600Odtwarzam ten sam problem i jest to naprawdę denerwujące. Znalazłem te przydatne:
HttpClient - obsługa wyjątków agregujących
Błąd w HttpClient.GetAsync powinien zgłaszać WebException, a nie TaskCanceledException
Jakiś kod na wypadek, gdyby linki nigdzie nie prowadziły:
źródło
WebException
można złapać. Może to pomoże.default(CancellationToken)
przed porównaniem zex.CancellationToken
.Zauważyłem, że najlepszym sposobem ustalenia, czy upłynął limit czasu wywołania usługi, jest użycie tokenu anulowania, a nie właściwości limitu czasu HttpClient:
A następnie obsłuż wyjątek CancellationException podczas wezwania serwisowego ...
Oczywiście, jeśli przekroczenie limitu czasu występuje po stronie usług, powinno to być obsługiwane przez WebException.
źródło
cts.Token.IsCancellationRequested
jesttrue
to musi oznaczać, że limit czasu wystąpił?Z http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.timeout.aspx
Następnie uzyskasz dostęp do
Status
właściwości, zobacz WebExceptionStatusźródło
AggregateException
zTaskCancelledException
wnętrzem. Muszę robić coś złego ...catch(WebException e)
?AggregateException
jest nieobsługiwany. Jeśli tworzysz projekt konsoli VS, dodaj odwołanie doSystem.Net.Http
i upuść kod domain
, możesz się o tym przekonać (jeśli chcesz).TaskCanceledException
. Wydaje się, że jest to spowodowane wewnętrzną obsługą limitu czasu TPL na wyższym poziomie niżHttpWebClient
. Wydaje się, że nie ma dobrego sposobu na rozróżnienie między anulowaniem limitu czasu a anulowaniem użytkownika. W rezultacie możesz nie miećWebException
w swoimAggregateException
.Zasadniczo musisz przechwycić
OperationCanceledException
i sprawdzić stan tokenu anulowania, który został przekazany doSendAsync
(GetAsync
lub dowolnejHttpClient
metody, której używasz):IsCancellationRequested
prawda), oznacza to, że żądanie rzeczywiście zostało anulowaneOczywiście nie jest to zbyt wygodne ... lepiej byłoby otrzymać
TimeoutException
w przypadku przekroczenia limitu czasu. Proponuję tutaj rozwiązanie oparte na niestandardowej obsłudze komunikatów HTTP: Lepsza obsługa limitu czasu dzięki HttpClientźródło
HttpClient.Timeout
nieskończoność?jest tym, co zwykle robię, wydaje mi się, że działa całkiem nieźle, jest szczególnie dobry, gdy używam proxy.
źródło