J’ai le code de test suivant. J’ai toujours l’erreur “Tâche a été annulée” après avoir bouclé 316934 ou 361992 fois.
Si je ne me trompe pas, il y a deux raisons possibles pour lesquelles la tâche a été annulée a) HttpClient a expiré ou b) trop de tâches dans la queue et certaines tâches ont expiré.
Je n’ai pas pu trouver la documentation sur la limitation dans la mise en queue des tâches. Et j’ai essayé de créer plus de 500 000 tâches et pas de délai d’attente. Je suppose que la raison “b” pourrait ne pas être correcte.
Q1. Y a-t-il une autre raison pour laquelle j’ai manqué?
Q2. Si c’est parce que le délai d’attente HttpClient, comment puis-je obtenir le message d’exception exact au lieu de l’exception “TaskCancellation”.
Q3. Quel serait le meilleur moyen de le réparer? Dois-je présenter le étrangleur?
Merci!
var _httpClient = new HttpClient(); _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml"); _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate"); _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0"); _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Charset", "ISO-8859-1"); int[] intArray = Enumerable.Range(0, 600000).ToArray(); var results = intArray .Select(async t => { using (HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "http://www.google.com")) { log.Info(t); try { var response = await _httpClient.SendAsync(requestMessage); var responseContent = await response.Content.ReadAsSsortingngAsync(); return responseContent; } catch (Exception ex) { log.ErrorException(ssortingng.Format("SoeHtike {0}", Task.CurrentId), ex); } return null; } }); Task.WaitAll(results.ToArray()); Console.ReadLine();
Voici l’étape pour reproduire le problème.
Créez un projet de console dans VS 2012.
Veuillez copier et coller mon code dans Main.
Placez le point d’arrêt à cette ligne “log.ErrorException (ssortingng.Format (” SoeHtike {0} “, Task.CurrentId), ex);”
Exécutez le programme en mode débogage. Attendez quelques minutes. (peut-être 5 minutes?) Je viens de tester mon code et j’ai eu l’exception après 3 minutes. Si vous avez un violon, vous pouvez surveiller les demandes pour savoir si le programme est toujours en cours d’exécution.
N’hésitez pas à me faire savoir si vous ne pouvez pas reproduire le problème.
La valeur par défaut de HttpClient.Timeout
est 100 secondes (00:01:40). Si vous faites un horodatage dans votre bloc catch
, vous remarquerez que les tâches commencent à être annulées à ce moment précis. Apparemment, il y a un nombre limité de requêtes HTTP que vous pouvez faire par seconde, d’autres sont mises en queue. Les requêtes en queue sont annulées à l’expiration du délai. Sur les 600 000 tâches que j’ai accomplies, seules 2 500 ont réussi, d’autres ont été annulées.
Je trouve également peu probable que vous puissiez exécuter l’ensemble des 600 000 tâches. De nombreux pilotes réseau ne laissent passer un grand nombre de requêtes que pendant une courte période et réduisent ce nombre à une valeur très faible après un certain temps. Ma carte réseau m’a permis d’envoyer seulement 921 requêtes en 36 secondes et de réduire cette vitesse à une seule requête par seconde. À cette vitesse, il faudra une semaine pour accomplir toutes les tâches.
Si vous êtes en mesure de contourner cette limitation, assurez-vous de créer le code pour la plate-forme 64 bits car l’application a très envie de mémoire.
Ne jetez pas l’instance de HttpClient que vous utilisez. Bizarre mais corrigé pour moi ce problème.
Je voulais juste partager J’ai eu un code similaire pour tester nos serveurs, et il est fort probable que vos demandes expirent. Vous pouvez définir le délai d’expiration de votre requête http au maximum et voir si cela change quelque chose pour vous. J’ai essayé de bash nos serveurs en créant différents threads. Et cela a augmenté les hits mais ils finiraient tous par expirer.Et aussi, vous ne pouvez pas définir un délai d’attente lorsque vous les frappez sur un autre thread.