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

3 ответов


есть 2 вероятных причины, по которым a TaskCanceledException будут брошены:

  1. что-то под названием Cancel() на CancellationTokenSource связанный с токеном отмены до завершения задачи.
  2. истекло время ожидания запроса, т. е. не было завершено в течение периода времени, указанного в HttpClient.Timeout.

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

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

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

решением было позвонить myTask.GetAwaiter().GetResult() на Main() (от ответ).


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