2013-10-01 2 views
48

У меня есть следующий тестовый код. Я всегда получаю ошибку «Задача была отменена» после цикла 316934 или 361992 раз.HttpClient - задача была отменена - Как получить точное сообщение об ошибке?

Если я не ошибаюсь, возможны две причины, по которым задача была отменена.) HttpClient получил тайм-аут или b) слишком много задач в очереди, а некоторые задачи получили тайм-аут.

Я не смог найти документацию об ограничении в очередности задач. И я попытался создать более 500 тыс. Задач и без тайм-аута. Думаю, причина «b» может быть неправильной.

Q1. Есть ли еще одна причина, по которой я пропустил?

Q2. Если это потому, что тайм-аут HttpClient, как я могу получить точное сообщение исключения вместо исключения «TaskCancellation».

Q3. Какой был бы лучший способ исправить это? Должен ли я ввести дроссель?

Спасибо!

var _httpClient = new HttpClient(); 
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml"); 
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate"); 
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0"); 
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Charset", "ISO-8859-1"); 

int[] intArray = Enumerable.Range(0, 600000).ToArray(); 

var results = intArray     
    .Select(async t => { 

     using (HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "http://www.google.com")) { 
      log.Info(t); 

      try { 

       var response = await _httpClient.SendAsync(requestMessage); 
       var responseContent = await response.Content.ReadAsStringAsync(); 

       return responseContent; 
      } 
      catch (Exception ex) { 
       log.ErrorException(string.Format("SoeHtike {0}", Task.CurrentId), ex); 
      } 
      return null; 
     } 
    }); 

Task.WaitAll(results.ToArray()); 

Console.ReadLine(); 

Вот этот шаг, чтобы воспроизвести проблему.

  1. Создание проекта консоли в VS 2012.

  2. Пожалуйста, скопируйте и вставьте свой код в Main.

  3. Поместите контрольную точку на этой линии "log.ErrorException (String.Format (" SoeHtike {0} " Task.CurrentId), ех);"

Запуск программы в режиме отладки. Подождите несколько минут. (может быть, 5 минут?) Я только что проверил свой код, и я получил исключение через 3 минуты. Если у вас есть скрипач, вы можете отслеживать запросы, чтобы вы знали, что программа все еще работает или нет.

Не стесняйтесь, дайте мне знать, если вы не можете воспроизвести проблему.

+2

Что вы делаете, так это то, что страница 600.000 эффективно DOS Attack, и вы не должны этого делать. –

+1

Привет, я понимаю. Но есть некоторые сайты, которые могут обрабатывать огромные запросы. И мне очень нравится знать, почему я получил «Задача была отменена» без фактического сообщения об ошибке. –

+0

и плюс, я не думаю, что это сайт, который блокирует мой запрос –

ответ

63

Значение по умолчанию HttpClient.Timeout составляет 100 секунд (00:01:40). Если вы сделаете отметку времени в своем блоке catch, вы заметите, что задачи начнут отменяться точно в это время. По-видимому, существует ограниченное количество HTTP-запросов, которые вы можете делать в секунду, а другие - в очереди. Запросы в очереди отправляются в таймаут. Из всех 600 тыс. Задач я лично получил только 2500 успешных, другие были отменены.

Я также считаю маловероятным, что вы сможете запустить всего 600000 задач. Многие сетевые драйверы пропускают большое количество запросов только в течение небольшого времени и через некоторое время сокращают это число до очень низкого значения. Моя сетевая карта позволила мне отправить всего 921 запрос в течение 36 секунд и опустила эту скорость только на один запрос в секунду. При такой скорости выполнения всей задачи потребуется неделя.

Если вы можете обойти это ограничение, убедитесь, что вы создаете код для 64-битной платформы, так как приложение очень голодны для памяти.

+0

привет, не могли бы вы подробнее рассказать о своих ответах. Я получаю ту же проблему. Как узнать, сколько задач выполняется в моем приложении? – user123456

+0

Время ожидания. Спасибо, вот что я искал. – frostymarvelous

1

просто хотел поделиться У меня был аналогичный код для загрузки наших серверов и высокая вероятность того, что ваши запросы будут отключены. Вы можете установить тайм-аут для вашего HTTP-запроса max и посмотреть, не изменит ли он что-либо для вас. Я попытался поразить наши серверы, создав различные потоки. И это увеличило количество просмотров, но все они в конечном итоге истекали. А также вы не можете установить тайм-аут, когда попадаете в другой поток.

32

Не используйте экземпляр HttpClient, который вы используете. Странно, но исправил для меня эту проблему.

+0

Я создавал только консольное приложение, чтобы отправлять много запросов в API, чтобы имитировать «реальный» мировой случай, и это было единственное, что сработало для меня. Очень странно. – jpgrassi

+0

Вау, я с этим схожу, и ... твоя единственная вещь, которая ее исправила. Делал более или менее то же, что и @jpgrassi. – Veverke

+1

это было! спасибо – JobaDiniz

Смежные вопросы