L’appel d’une méthode asynchrone à l’aide d’un Task.Run semble incorrect?

Je suis récemment tombé sur ce code écrit par un sous-traitant qui travaillait pour nous. C’est soit diaboliquement intelligent ou stupide (je pense que le dernier mais je voulais un deuxième avis). Je ne suis pas massivement au courant des async .

En gros, cela a fonctionné comme ceci:

 public bool Send(TemplatedMessageDto message) { return Task.Run(() => SendAsync(message)) .GetAwaiter() .GetResult(); } public async Task SendAsync(TemplatedMessageDto message) { //code doing stuff var results = await _externalresource.DothingsExternally(); //code doing stuff } 

Maintenant, si je comprends bien, le premier Task.Run() est inutile et inefficace? et devrait vraiment être:

 public bool Send(TemplatedMessageDto message) { return SendAsync(message)) .GetAwaiter() .GetResult(); } public async Task SendAsync(TemplatedMessageDto message) { //code doing stuff var results = await _externalresource.DothingsExternally(); //code doing stuff } 

Je ne suis pas non plus convaincu qu’il s’agisse vraiment d’une méthode asynchrone car elle attendra toujours, non? Je pense que son seul avantage (même ré-écrit) est de libérer le principal thread de travail.

Quelqu’un peut-il confirmer que cette première tâche ne devrait pas être là?

Je ne suis pas non plus convaincu qu’il s’agisse vraiment d’une méthode asynchrone car elle attendra toujours, non?

Ce n’est pas, comme l’explique Yuval. Vous ne devriez pas utiliser la synchronisation sur asynchrone.

Maintenant, si je comprends bien, le premier Task.Run() est inutile et inefficace?

Pas vraiment, utiliser Task.Run de cette manière est utile.

Puisque vous bloquez une méthode asynchrone (ce que vous ne devriez pas faire), il y a une chance que vous vous retrouviez dans une impasse. Cela se produit dans les applications d’interface utilisateur et asp.net où vous avez un SynchronizationContext .

L’utilisation de Task.Run efface SynchronizationContext car il délègue le travail à un thread ThreadPool et supprime le risque de blocage.

Donc, bloquer est mauvais, mais si vous Task.Run par le faire, utilisez Task.Run est plus sûr.

Je ne suis pas non plus convaincu qu’il s’agisse vraiment d’une méthode asynchrone car elle attendra toujours, non?

Ce que votre entrepreneur a fait, c’est utiliser l’ anti-motif asynchrone sync over . Il l’a probablement fait pour éviter de créer une méthode supplémentaire fonctionnant de manière synchrone. Il appelle inutilement Task.Run et le bloque immédiatement à l’aide de GetResult .

À l’aide de GetAwaiter().GetResult() l’exception interne, le cas échéant, à la place de la exception AggregateException .

Je pense que son seul avantage (même ré-écrit) est de libérer le principal thread de travail.

Votre version et la sienne vont bloquer le thread principal lors de l’exécution, tandis que le sien utilisera également un thread threadpool. Comme Bar l’a mentionné, cela peut aider à éviter les blocages liés aux problèmes de marshaling du contexte de synchronisation. Je recommanderais de créer un équivalent synchrone si nécessaire.