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

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

但是,如果关闭服务器, HttpClient大约20秒才能返回正确的exception,例如图片中的exception。 在此处输入图像描述

我希望看到这个exception超过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; 

如msdn中所述,你无法通过超时来处理这个问题:

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

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

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

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

你可以使用这种不阻塞线程的方法( Task.Wait 阻塞线程 )

 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;