HttpClient - 如何判断服务器是否更快停机?

时间:2014-11-20 10:43:12

标签: c# .net http dotnet-httpclient

我使用.NET HttpClient向我的服务器发送请求。我已将HttpClient.Timeout属性设置为10秒,因此每当服务器在不到10秒的时间内无法处理我的请求时,我就会收到A task was cancelled异常。好到这里。

但是,如果服务器关闭,则HttpClient大约需要20秒才能返回正确的异常,例如图片中的异常。 enter image description here

我希望看到这个异常超过1​​0秒能够区分Server Down和Operation花了太长时间的情况。我在msdn文档中找不到任何相关内容。是否可以在HttpClient上设置超时?

以下是我如何构建HttpClient

 var webRequestHandler = new WebRequestHandler
        {
            UseProxy = false,
            Proxy = null,
            AllowPipelining = false,
            ContinueTimeout = TimeSpan.Zero,
            UseCookies = false,
            AllowAutoRedirect = false,
        };
 var httpClient = new HttpClient(webRequestHandler);
 httpClient.Timeout = timeout;

  httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "application/json");
  httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", userAgent);
  httpClient.DefaultRequestHeaders.ExpectContinue = false;

2 个答案:

答案 0 :(得分:9)

这个答案只是扩展了@ brz的例子。

您可以使用此方法不会阻止该帖子(Task.Wait blocks the thread

var timeout = Task.Delay(10000); // 10 seconds timeout
var request = httpClient.GetAsync("http://www.google.com");

await Task.WhenAny(timeout, request); // wait for either timeout or the request

if (timeout.IsCompleted) // if the timeout ended first, then handle it
{
    // handle timeout
}

// otherwise continue processing the request result
var response = await request;

答案 1 :(得分:3)

msdn

中所述,您无法通过超时处理此问题
  

域名系统(DNS)查询最多可能需要15秒才能返回或超时。如果您的请求包含需要解析的主机名,并且您将Timeout设置为小于15秒的值,则可能需要15秒或更长时间才会抛出WebException以指示请求超时。

但是,另一种方法是将请求包装在另一个任务中并从那里处理超时:

var task = Task.Run(() => { 
                var req = new HttpClient().GetAsync("http://www.google.com");
                if (!req.Wait(10000))//wait for 10 seconds
                    throw new TaskCanceledException(req);
            });
task.Wait();