HttpClient - задача была отменена?

Он отлично работает, когда у одной или двух задач возникает ошибка "Задача была отменена", когда у нас имеется более одной задачи.

enter image description here

List<Task> allTasks = new List<Task>();
allTasks.Add(....);
allTasks.Add(....);
Task.WaitAll(allTasks.ToArray(), configuration.CancellationToken);


private static Task<T> HttpClientSendAsync<T>(string url, object data, HttpMethod method, string contentType, CancellationToken token)
{
    HttpRequestMessage httpRequestMessage = new HttpRequestMessage(method, url);
    HttpClient httpClient = new HttpClient();
    httpClient.Timeout = new TimeSpan(Constants.TimeOut);

    if (data != null)
    {
        byte[] byteArray = Encoding.ASCII.GetBytes(Helper.ToJSON(data));
        MemoryStream memoryStream = new MemoryStream(byteArray);
        httpRequestMessage.Content = new StringContent(new StreamReader(memoryStream).ReadToEnd(), Encoding.UTF8, contentType);
    }

    return httpClient.SendAsync(httpRequestMessage).ContinueWith(task =>
    {
        var response = task.Result;
        return response.Content.ReadAsStringAsync().ContinueWith(stringTask =>
        {
            var json = stringTask.Result;
            return Helper.FromJSON<T>(json);
        });
    }).Unwrap();
}

Ответ 1

Есть 2 возможных причины, по которым будет :

  • Что-то называемое Cancel() на CancellationTokenSource, связанное с токеном отмены до завершения задачи.
  • Истекло время ожидания запроса, то есть не завершено в течение времени, указанного вами в HttpClient.Timeout.

Мое предположение - это таймаут. (Если это была явная аннулирование, вы, вероятно, поняли бы это.) Вы можете быть более уверенным, проверяя исключение:

try
{
    var response = task.Result;
}
catch (TaskCanceledException ex)
{
    // Check ex.CancellationToken.IsCancellationRequested here.
    // If false, it pretty safe to assume it was a timeout.
}

Ответ 2

Я столкнулся с этой проблемой, потому что мой метод Main() не ожидал завершения задачи перед возвратом, поэтому Task<HttpResponseMessage> myTask отменяется, когда моя консольная программа завершена.

Решение заключалось в вызове myTask.GetAwaiter().GetResult() в Main() (из этого ответа).

Ответ 3

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

Ответ 4

Другая причина может заключаться в том, что если вы запускаете службу (API) и ставите точку останова в службе (а ваш код застревает на некоторой точке останова (например, решение Visual Studio показывает отладку вместо выполняется))). а затем нажав API из клиентского кода. Так что, если служебный код приостановлен на некоторой точке останова, вы просто нажимаете F5 в VS.

Ответ 5

var clientHttp = new HttpClient();
clientHttp.Timeout = TimeSpan.FromMinutes(30);

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

Другими словами, запрос не будет ждать 30 минут, если он получит результаты до 30 минут. 30 минут означает, что время обработки запроса составляет 30 минут. Когда произошла ошибка "Задача была отменена", или возникли большие требования к данным.