Как я могу узнать, когда истечет время ожидания HttpClient?
Насколько я могу судить, нет способа узнать, что это именно тайм-аут, который произошел. Разве я не смотрю в нужном месте, или я не хватает чего-то большего?
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);
}
Это возвращает:
Произошла одна или несколько ошибок.
Задача была отменена.
Ответы
Ответ 1
Вам нужно подождать 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);
}
Ответ 2
Я воспроизвожу ту же проблему, и это действительно раздражает. Я нашел их полезными:
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!?)
}
}
Ответ 3
Я обнаружил, что лучший способ определить, был ли тайм-аут службы, - использовать токен отмены, а не свойство времени ожидания HttpClient:
var cts = new CancellationTokenSource();
cts.CancelAfter(timeout);
И затем обработайте исключение CancellationException во время вызова службы...
catch(TaskCanceledException)
{
if(!cts.Token.IsCancellationRequested)
{
// Timed Out
}
else
{
// Cancelled for some other reason
}
}
Конечно, если тайм-аут происходит на стороне обслуживания вещей, это должно иметь возможность обрабатывать WebException.
Ответ 4
От http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.timeout.aspx
Запрос системы доменных имен (DNS) может занять до 15 секунд для возврата или тайм-аута. Если ваш запрос содержит имя хоста, для которого требуется разрешение, и вы установите Timeout на значение менее 15 секунд, это может занять 15 секунд или более, прежде чем выйдет WebException, чтобы указать тайм-аут вашего запроса.
Затем вы получите доступ к свойству Status
, см. WebExceptionStatus