Cela fonctionne bien quand avoir une ou deux tâches génère 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();
}
c#
task-parallel-library
dotnet-httpclient
Karthikeyan Vijayakumar
la source
la source
CancellationToken
comme paramètre et ne l'utilisez pas?HttpClient
par erreur, par exempleasync Task<HttpResponseMessage> Method(){ using(var client = new HttpClient()) return client.GetAsync(request); }
HttpClient
comme @JobaDiniz (avec unusing()
), veuillez arrêter! La raison: aspnetmonsters.com/2016/08/2016-08-27-httpclientwrongRéponses:
Il y a 2 raisons probables pour lesquelles un
TaskCanceledException
serait jeté:Cancel()
leCancellationTokenSource
associé au jeton d'annulation avant la fin de la tâche.HttpClient.Timeout
.Je suppose que c'était un temps mort. (S'il s'agissait d'une annulation explicite, vous l'auriez probablement compris.) Vous pouvez être plus certain en inspectant l'exception:
la source
httpClient.Timeout = TimeSpan.FromMinutes(30)
TimeSpan.FromMilliseconds(Configuration.HttpTimeout)
plutôt quenew TimeSpan(Configuration.HttpTimeout)
travailler un régal. Merci!httpClient.Timeout = TimeSpan.FromMinutes(30)
n'est pas une bonne approche, car il bloquera ce thread particulier pendant 30 minutes et n'atteindra pas non plus le point de terminaison HTTP (qui est votre tâche principale). De plus, si votre programme se termine avant 30 minutes, vous êtes plus susceptible de rencontrerThreadAbortException
. Une meilleure approche serait de découvrir pourquoi ce point de terminaison HTTP n'est pas touché, il peut nécessiter un VPN ou un accès réseau restreint.await
, aucun thread n'est bloqué. Pas le thread d'interface utilisateur, pas un thread de threadpool autre thread d'arrière-plan, aucun.J'ai rencontré ce problème car ma
Main()
méthode n'attendait pas que la tâche soit terminée avant de revenir, donc leTask<HttpResponseMessage> myTask
était en cours d'annulation lorsque mon programme de console s'est arrêté.La solution était d'appeler
myTask.GetAwaiter().GetResult()
àMain()
(de cette réponse ).la source
Une autre possibilité est que le résultat ne soit pas attendu côté client. Cela peut se produire si l'une des méthodes de la pile d'appels n'utilise pas le mot clé await pour attendre la fin de l'appel.
la source
Ce qui précède est la meilleure approche pour attendre une demande importante. Vous êtes confus environ 30 minutes; c'est un temps aléatoire et vous pouvez donner le temps que vous voulez.
En d'autres termes, la requête n'attendra pas 30 minutes si elle obtient des résultats avant 30 minutes. 30 min signifie que le temps de traitement de la demande est de 30 min. Lorsque nous nous sommes produits, l'erreur «La tâche a été annulée» ou les exigences de demande de données volumineuses.
la source
Une autre raison peut être que si vous exécutez le service (API) et mettez un point d'arrêt dans le service (et que votre code est bloqué à un point d'arrêt (par exemple, la solution Visual Studio affiche le débogage au lieu de l' exécution )). puis frapper l'API à partir du code client. Donc, si le code de service s'est interrompu sur un point d'arrêt, vous appuyez simplement sur F5 dans VS.
la source
Dans ma situation, la méthode du contrôleur n'était pas asynchrone et la méthode appelée à l'intérieur de la méthode du contrôleur était async.
Je suppose donc qu'il est important d'utiliser async / await jusqu'au niveau supérieur pour éviter des problèmes comme ceux-ci.
la source