Подтвердить что ты не робот

Как я могу узнать, когда истечет время ожидания 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);
}

Это возвращает:

Произошла одна или несколько ошибок.

Задача была отменена.

4b9b3361

Ответ 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