HttpClient - une tâche a été annulée?

Cela fonctionne bien quand une ou deux tâches génère cependant une erreur "une tâche a été annulée" lorsque nous avons plus d'une tâche répertoriée.

entrez la description de l'image ici

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();
}
120
demandé sur abatishchev 2015-03-21 09:15:49

3 réponses

Il y a 2 raisons probables pour lesquelles un TaskCanceledException serait lancé:

  1. quelque chose appelé Cancel() sur le CancellationTokenSource associé au jeton d'annulation avant la fin de la tâche.
  2. la requête a expiré, c'est-à-dire qu'elle ne s'est pas terminée dans le délai que vous avez spécifié sur HttpClient.Timeout.

Je suppose que c'était un délai d'attente. (Si c'était une annulation explicite, vous auriez probablement compris cela.) Vous pouvez être plus certain en inspectant l'exception:

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.
}
172
répondu Todd Menier 2015-03-23 15:33:08

J'ai rencontré ce problème parce que ma méthode Main() n'attendait pas la fin de la tâche avant de revenir, donc le Task<HttpResponseMessage> myTask était annulé à la sortie de mon programme de console.

, La solution a été d'appeler myTask.GetAwaiter().GetResult() dans Main() (à partir de cette réponse).

10
répondu Ben Hutchison 2017-09-10 02:41:10

Une autre possibilité est que le résultat n'est pas attendu du côté client. Cela peut se produire si une méthode sur la pile d'appels n'utilise pas le mot-clé await pour attendre la fin de l'appel.

8
répondu Manish 2017-09-10 15:15:19