Programmation asynchrone en C# : guide complet pour débutants
\n\nLa programmation asynchrone est l'un des concepts clés du développement moderne en C#. Elle permet à vos applications de rester réactives sans bloquer le fil d'exécution lors d'opérations longues : lecture de fichiers, requêtes à une base de données ou appels HTTP. Dans ce guide, nous allons explorer les bases de l'asynchronisme en C# à l'aide d'exemples pratiques.
\n\nQu'est-ce que la programmation asynchrone et pourquoi en a-t-on besoin ?
\n\nEn programmation synchrone, le code s'exécute séquentiellement. Si vous appelez une méthode qui attend une réponse du serveur pendant 5 secondes, tout le fil (UI ou de travail) se fige. L'application "se bloque". La programmation asynchrone résout ce problème : au lieu de bloquer le fil, la méthode rend le contrôle au code appelant, et lorsque le résultat est prêt, elle le notifie.
\n\nLes principaux avantages de l'asynchronisme :
\n- \n
- Réactivité de l'interface utilisateur — l'interface ne se bloque pas lors d'opérations longues. \n
- Évolutivité — les applications serveur peuvent traiter plus de requêtes sans créer de nouveaux threads. \n
- Efficacité — les threads libérés sont utilisés pour d'autres tâches. \n
Les bases de async/await en C#
\n\nLes mots-clés async et await sont la base de la programmation asynchrone en C#. Ils sont apparus dans C# 5.0 et ont rendu le code asynchrone presque aussi simple que le code synchrone.
Règles d'utilisation :
\n- \n
- La méthode est marquée avec le mot-clé
async. \n - Le type de retour doit être
Task,Task<T>ouvoid(uniquement pour les gestionnaires d'événements). \n - À l'intérieur de la méthode, appelez d'autres méthodes asynchrones avec le mot-clé
await. \n
Exemple simple :
\nusing System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\n\nclass Program\n{\n static async Task Main(string[] args)\n {\n Console.WriteLine("Début du téléchargement...");\n string content = await DownloadWebPageAsync("https://example.com");\n Console.WriteLine($"Nombre de caractères téléchargés : {content.Length}");\n }\n\n static async Task<string> DownloadWebPageAsync(string url)\n {\n using HttpClient client = new HttpClient();\n string result = await client.GetStringAsync(url);\n return result;\n }\n}\n\nNotez que la méthode Main est également marquée comme async Task — cela est autorisé depuis C# 7.1.
Les types Task, Task<T> et ValueTask
\n\nEn programmation asynchrone C#, trois principaux types de valeurs de retour sont utilisés :
\n\n- \n
Task— pour les méthodes qui ne retournent pas de valeur (équivalent de void). \n Task<T>— pour les méthodes qui retournent une valeur de type T. \n ValueTask<T>— version optimisée pour les scénarios où le résultat est souvent disponible de manière synchrone (par exemple, depuis un cache). \n
Exemple avec Task<T> :
\nstatic async Task<int> CalculateSumAsync(int a, int b)\n{\n await Task.Delay(1000); // Simulation d'une opération longue\n return a + b;\n}\n\n// Appel :\nint result = await CalculateSumAsync(5, 3);\nConsole.WriteLine(result); // 8\n\nGestion des erreurs dans les méthodes asynchrones
\n\nLes exceptions dans les méthodes asynchrones sont gérées avec le bloc standard try-catch. Cependant, il y a une nuance importante : l'exception est stockée dans l'objet Task et est "relancée" lors de l'utilisation de await.
static async Task<string> ReadFileAsync(string path)\n{\n try\n {\n string content = await File.ReadAllTextAsync(path);\n return content;\n }\n catch (FileNotFoundException ex)\n {\n Console.WriteLine($"Fichier non trouvé : {ex.Message}");