[C#] 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);
}

이것은 다음을 반환합니다.

하나 이상의 오류가 발생했습니다.

작업이 취소되었습니다.



답변

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);
}


답변

나는 같은 문제를 재현하고 있으며 실제로 성가시다. 나는 이것들이 유용하다는 것을 알았다.

HttpClient-집계 예외 처리

HttpClient.GetAsync의 버그는 TaskCanceledException이 아닌 WebException을 발생시킵니다.

링크가 어디에도없는 경우 일부 코드 :

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!?)
    }
}


답변

서비스 호출 시간이 초과되었는지 확인하는 가장 좋은 방법은 HttpClient의 시간 초과 속성이 아닌 취소 토큰을 사용하는 것입니다.

var cts = new CancellationTokenSource();
cts.CancelAfter(timeout);

그런 다음 서비스 호출 중에 CancellationException을 처리하십시오 …

catch(TaskCanceledException)
{
    if(!cts.Token.IsCancellationRequested)
    {
        // Timed Out
    }
    else
    {
        // Cancelled for some other reason
    }
}

물론 타임 아웃이 서비스 측에서 발생하면 WebException으로 처리 할 수 ​​있습니다.


답변

에서 http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.timeout.aspx

DNS (Domain Name System) 쿼리가 반환되거나 시간 초과되는 데 최대 15 초가 걸릴 수 있습니다. 요청에 해결이 필요한 호스트 이름이 포함되어 있고 제한 시간을 15 초 미만으로 설정하면 요청에서 제한 시간을 표시 하기 위해 WebException이 발생 하기까지 15 초 이상 걸릴 수 있습니다 .

그런 다음 Status속성에 액세스 하십시오. WebExceptionStatus를 참조하십시오.


답변

기본적으로, 당신 OperationCanceledException은 전달 된 취소 토큰의 상태를 확인 해야합니다 SendAsync(또는 사용중인 GetAsync모든 HttpClient방법).

  • 취소 된 경우 (IsCancellationRequested true) 요청이 실제로 취소되었음을 의미합니다.
  • 그렇지 않은 경우 요청 시간이 초과되었음을 의미합니다.

물론 이것은 매우 편리하지 않습니다 … TimeoutException시간 초과의 경우 수신하는 것이 좋습니다 . 커스텀 HTTP 메시지 핸들러를 기반으로 여기에 솔루션을 제안합니다 : HttpClient로 더 나은 시간 초과 처리


답변

_httpClient = new HttpClient(handler) {Timeout = TimeSpan.FromSeconds(5)};

내가 일반적으로하는 일, 꽤 잘 작동하는 것 같습니다. 프록시를 사용할 때 특히 좋습니다.


답변