2014-11-20 2 views
4

Я использую .NET HttpClient для отправки запросов на мой сервер. Я установил свойство HttpClient.Timeout на 10 секунд, поэтому я получаю исключение A task was cancelled всякий раз, когда сервер не обрабатывает мой запрос менее чем за 10 секунд. Хорошо, пока здесь.HttpClient - как выяснить, работает ли сервер быстрее?

Однако, если сервер выключен, для получения правильного исключения, такого как изображение на картинке, требуется HttpClient около ~ 20 секунд. enter image description here

Я бы хотел, чтобы это исключение было быстрее, чем 10 секунд, чтобы иметь возможность отличать сервер от «Вниз» и «Операция», было слишком длинным сценарием. Я не могу найти ничего об этом в документации 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; 
+1

Просто немного аналогии, что я хочу, чтобы вы думали о: Если вы по телефону с кем-то и задать вопрос , Есть ли у вас надежный (быстрый/немедленный) способ определить, спящий ли человек, с которым вы разговариваете, или просто размышляете об этом? – MrPaulch

+0

Логически то, что вы просите, не имеет смысла, вы не можете знать, если у вас не было ответа, потому что сервер не работает или слишком долго обрабатывается ваш запрос, вы просто не получили ответа. –

+0

Я думаю, что логически это имеет смысл, поскольку существует разница между ответом HTTP и TCP-соединением. – AlexDev

ответ

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

Этот ответ только расширяет @ пример БРЗ в.

Вы можете использовать этот подход, который не блокирует нить (Task.Waitblocks 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;