HttpClient - задача была отменена - Как получить точное сообщение об ошибке? - программирование
Подтвердить что ты не робот

HttpClient - задача была отменена - Как получить точное сообщение об ошибке?

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

Если я не ошибаюсь, есть две возможные причины, по которым задача была отменена. a) 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();

Ниже приведен шаг к репликации проблемы.

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

  • Скопируйте и вставьте мой код в Main.

  • Поместите точку останова в этой строке "log.ErrorException(string.Format(" SoeHtike {0}", Task.CurrentId), ех); "

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

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