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.
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 réponses
Il y a 2 raisons probables pour lesquelles un TaskCanceledException
serait lancé:
- quelque chose appelé
Cancel()
sur leCancellationTokenSource
associé au jeton d'annulation avant la fin de la tâche. - 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.
}
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).
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.