Async et Await en C# : sauver l'application des « blocages »
\n\nAvez-vous déjà lancé un programme en C#, cliqué sur un bouton, et l'interface a « gelé » pendant quelques secondes ? Ou peut-être votre serveur a-t-il cessé de répondre aux nouvelles requêtes pendant qu'une requête « lourde » était traitée ? Cela vous dit quelque chose ? C'est le problème classique du code synchrone, où le fil d'exécution est bloqué en attendant la fin d'une opération (lecture d'un fichier, requête à une base de données, appel HTTP).
\n\nLa solution à ce problème est la programmation asynchrone. Et en C#, les principaux outils pour cela sont les mots-clés async et await. Si vous vous êtes déjà demandé : « Comment et quand utiliser async et await ? » — vous êtes au bon endroit. Dans ce tutoriel, nous allons tout détailler, des bases aux meilleures pratiques, pour que vous écriviez un code rapide, réactif et évolutif.
Ce contenu est basé sur une question populaire réelle de Stack Overflow, qui a recueilli des milliers de vues. Nous l'avons adapté pour un contenu éducatif, en ajoutant des exemples de code et des explications claires.
\n\nQue sont async et await ? En termes simples
\n\nImaginez que vous êtes un chef cuisinier (votre programme). Vous devez préparer un dîner. L'un des plats est une soupe qui doit cuire 30 minutes. Dans un monde synchrone, vous resteriez devant la cuisinière à attendre que la soupe cuise, sans rien faire. Bête, non ?
\n\nL'asynchronisme — c'est quand vous mettez la soupe à cuire (async) et, sans attendre, vous commencez à couper la salade, à mettre la table et à faire d'autres choses. Quand la soupe est prête, vous y revenez (await). Vous ne perdez pas de temps — vous êtes efficace.
- \n
async— un modificateur de méthode qui indique au compilateur : « Cette méthode contient des opérations asynchrones. Ne bloque pas le fil quand je rencontreawait». \n await— un opérateur qui s'applique à une tâche (Task). Il dit : « Suspend l'exécution de cette méthode jusqu'à ce que la tâche soit terminée, mais ne bloque pas le fil. Une fois la tâche terminée, reprend l'exécution à partir de cet endroit ». \n
Important : await ne bloque pas le fil. Il rend le contrôle au code appelant, et le fil continue à exécuter d'autres travaux.
Quand utiliser async et await ?
\n\nC'est la question la plus fréquente. La réponse est simple : toujours lorsque vous effectuez une opération qui peut prendre beaucoup de temps (opérations I/O-bound) et que vous ne voulez pas bloquer le fil.
\n\nVoici les scénarios typiques :
\n- \n
- Requêtes réseau : Appels HTTP (HttpClient), travail avec WebSocket. \n
- Travail avec des fichiers : Lecture/écriture de gros fichiers, travail avec des flux. \n
- Requêtes à des bases de données : Entity Framework, ADO.NET, Dapper. \n
- Travail avec des services web : WCF, API REST. \n
- Toute opération d'entrée-sortie (I/O) : Accès au disque, au réseau, à l'imprimante. \n
Quand NE PAS utiliser async et await ?
\n- \n
- Opérations CPU-bound : Si votre tâche nécessite des calculs intensifs (rendu 3D, traitement vidéo, calculs mathématiques complexes),
async/awaitn'aidera pas. Ici, il faut utiliserTask.RunouParallelpour paralléliser sur plusieurs cœurs du processeur. \n - Dans les constructeurs de classes : Les constructeurs ne peuvent pas être async. Utilisez des méthodes d'usine (
public static async Task<MyClass> CreateAsync()). \n - Dans les getters/setters de propriétés : Ils ne peuvent pas non plus être async. Utilisez des méthodes. \n
Comment ça fonctionne ? Analyse avec un exemple de code
\n\nRegardons du code réel. Imaginez que nous chargeons des données depuis un serveur distant.
\n\nMauvais exemple (synchrone)
\npublic string GetDataFromWeb()\n{\n usi