TaskCanceledException lorsque vous n’attendez pas

Il semble que je reçois une TaskCanceledException chaque fois que je retourne une autre tâche de manière synchrone au lieu de l’attendre, en suivant les instructions données dans Quand enfin vous attendez .

Code d’anomalie TaskCanceledException

 public static class Download { public static Task FromYouTubeAsync(ssortingng videoUri) { using (var client = new HttpClient()) { return FromYouTubeAsync( () => client .GetSsortingngAsync(videoUri), uri => client .GetByteArrayAsync(uri)); } } public async static Task FromYouTubeAsync( Func<Task> sourceFactory, Func<string, Task> downloadFactory) { ssortingng source = await // TaskCanceledException here sourceFactory() .ConfigureAwait(false); // find links return await downloadFactory(links.First()) .ConfigureAwait(false); } } 

Code sans exception

Ici, la première surcharge de la signature de la méthode est modifiée en asynchrone et attend la seconde surcharge. Pour une raison quelconque, cela empêche l’ TaskCanceledException .

 public static class Download { public async static Task FromYouTubeAsync(ssortingng videoUri) { using (var client = new HttpClient()) { return await FromYouTubeAsync( () => client .GetSsortingngAsync(videoUri), uri => client .GetByteArrayAsync(uri)); } } public async static Task FromYouTubeAsync( Func<Task> sourceFactory, Func<string, Task> downloadFactory) { ssortingng source = await // No exception! sourceFactory() .ConfigureAwait(false); // find links return await downloadFactory(links.First()) .ConfigureAwait(false); } } 

Pourquoi cela se produit-il et que puis-je faire pour résoudre ce problème (en plus de l’ attente de la méthode, qui gaspille les ressources décrites dans le lien ci-dessus)?

Désolé, le lien que vous avez posté concerne l’ application d’une optimisation qui ne s’applique que si la méthode ne fait rien après son await . Pour citer le post:

Dans ce cas, cependant, une tâche nous est confiée pour représenter la dernière instruction de la méthode. Il s’agit donc déjà d’une représentation du traitement complet de la méthode …

Dans votre exemple, la tâche ne représente pas la dernière instruction de la méthode. Regarde encore:

 public async static Task FromYouTubeAsync(ssortingng videoUri) { using (var client = new HttpClient()) { return await FromYouTubeAsync(...); } } 

Il se passe quelque chose après l’ await : spécifiquement, l’élimination du client . Donc, l’optimisation mentionnée dans cet article de blog ne s’applique pas ici .

C’est pourquoi vous voyez une exception si vous essayez de renvoyer la tâche directement:

 public static Task FromYouTubeAsync(ssortingng videoUri) { using (var client = new HttpClient()) { return FromYouTubeAsync(...); } } 

Ce code démarre le téléchargement, élimine ensuite HttpClient , puis renvoie la tâche. HttpClient annulera toutes les opérations en HttpClient .

Le code utilisant wait await (de manière asynchrone) la fin de l’opération HTTP avant de disposer du HttpClient . C’est le comportement dont vous avez besoin et await est le moyen le plus propre de l’exprimer. Dans ce cas, ce n’est pas du tout un “gaspillage de ressources”, car vous devez différer l’élimination jusqu’à la fin du téléchargement.