Насколько я могу судить, нет никакого способа узнать, что это именно тайм-аут. Я ищу не в том месте или мне не хватает чего-то большего?
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);
}
Это возвращает:
Произошла одна или несколько ошибок.
Задание отменено.
c#
timeout
dotnet-httpclient
Бенджол
источник
источник
Ответы:
Вам нужно дождаться
GetAsync
метода. Затем он выдаст,TaskCanceledException
если истекло время ожидания. Кроме того,GetStringAsync
иGetStreamAsync
внутренне обрабатывают тайм-аут, поэтому они НИКОГДА не будут вызывать.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); }
источник
GetStreamAsync
бросилTaskCanceledException
мне.TaskCanceledException
вызвано ли это тайм-аутом HTTP, а не прямой отменой или другой причиной?TaskCanceledException.CancellationToken.IsCancellationRequested
. Если false, вы можете быть уверены, что это был тайм-аут.IsCancellationRequested
получение токена исключения при прямой отмене, как я думал ранее: stackoverflow.com/q/29319086/62600Я воспроизвожу ту же проблему, и это очень раздражает. Я нашел это полезным:
HttpClient - работа с совокупными исключениями
Ошибка в HttpClient.GetAsync должна вызывать WebException, а не TaskCanceledException
Код на случай, если ссылки никуда не денутся:
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!?) } }
источник
WebException
можно поймать. Возможно, это поможет.default(CancellationToken)
до сравнения сex.CancellationToken
.Я обнаружил, что лучший способ определить, истек ли время ожидания вызова службы, - использовать токен отмены, а не свойство тайм-аута HttpClient:
var cts = new CancellationTokenSource(); cts.CancelAfter(timeout);
А затем обработайте исключение CancellationException во время вызова службы ...
catch(TaskCanceledException) { if(!cts.Token.IsCancellationRequested) { // Timed Out } else { // Cancelled for some other reason } }
Конечно, если тайм-аут происходит на стороне службы, это должно обрабатываться с помощью WebException.
источник
cts.Token.IsCancellationRequested
этоtrue
должно означать , что тайм - аут произошел?Из http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.timeout.aspx
Затем вы получаете доступ к
Status
свойству, см. WebExceptionStatusисточник
AggregateException
сTaskCancelledException
внутренней стороны. Я, должно быть, делаю что-то не так ...catch(WebException e)
?AggregateException
это останется без внимания. Если вы создаете проект консоли VS, добавляете ссылкуSystem.Net.Http
и перетаскиваете кодmain
, вы можете убедиться в этом сами (если хотите).TaskCanceledException
. Кажется, это вызвано внутренней обработкой тайм-аута TPL на более высоком уровне, чемHttpWebClient
. Там , кажется, не быть хорошим способом отличить отмены тайм - аута и отмены пользователем. В результате вы можете не получитьWebException
в своемAggregateException
.По сути, вам нужно поймать
OperationCanceledException
и проверить состояние токена отмены, который был переданSendAsync
(илиGetAsync
, или любой другойHttpClient
метод, который вы используете):IsCancellationRequested
правда), значит, запрос действительно был отмененКонечно, это не очень удобно ... лучше бы получить
TimeoutException
в случае таймаута. Я предлагаю здесь решение, основанное на настраиваемом обработчике HTTP-сообщений: Лучшая обработка тайм-аута с помощью HttpClientисточник
HttpClient.Timeout
бесконечность?_httpClient = new HttpClient(handler) {Timeout = TimeSpan.FromSeconds(5)};
это то, что я обычно делаю, кажется, у меня неплохо получается, особенно хорошо при использовании прокси.
источник