Asynchrone Programmierung in C#: Vollständiger Leitfaden mit Beispielen

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einführung in die asynchrone Programmierung in C#



Asynchrone Programmierung ist eines der Schlüsselkonzepte der modernen C#-Entwicklung. Im Zeitalter von stark ausgelasteten Webanwendungen, Microservices und Cloud-Lösungen ist die Fähigkeit, effektiv mit Asynchronität zu arbeiten, zu einer unverzichtbaren Fähigkeit für jeden .NET-Entwickler geworden.



Das Hauptziel der asynchronen Programmierung ist es, den Ausführungsthread während des Wartens auf langwierige Operationen (E/A, Netzwerkarbeit, Datenbankabfragen) nicht zu blockieren. Stattdessen wird der Thread freigegeben, um andere Aufgaben zu bearbeiten, was die Leistung und Skalierbarkeit der Anwendung erheblich verbessert.



In diesem Artikel werden wir behandeln:

  • Grundlagen von async/await in C#
  • Arbeit mit der Task-Klasse
  • Regeln zum Schreiben asynchroner Methoden
  • Typische Fehler und wie man sie vermeidet


Grundlagen von async/await in C#



Das zentrale Paradigma der asynchronen Programmierung in C# basiert auf zwei Schlüsselwörtern: async und await. Sie wurden in C# 5.0 eingeführt und sind seitdem zum Standard für die Arbeit mit Asynchronität geworden.



Wie async/await funktioniert



Das Schlüsselwort async wird verwendet, um eine asynchrone Methode zu deklarieren. await wird auf eine Aufgabe (Task) angewendet, um die Ausführung der Methode bis zu deren Abschluss anzuhalten, ohne dabei den aktuellen Thread zu blockieren.



public async Task<string> GetDataAsync(){    // Simulation einer asynchronen HTTP-Anfrage    using var client = new HttpClient();    string result = await client.GetStringAsync("https://api.example.com/data");    return result;}

public async Task ProcessAsync(){ string data = await GetDataAsync(); Console.WriteLine($"Daten empfangen: {data}");}


Es ist wichtig zu verstehen: await blockiert den Thread nicht. Es übergibt die Kontrolle an den aufrufenden Code, und wenn die Aufgabe abgeschlossen ist, setzt die Methode die Ausführung an derselben Stelle fort.



Rückgabetypen asynchroner Methoden



Eine asynchrone Methode kann einen von drei Typen zurückgeben:

  • Task — für Methoden, die keinen Wert zurückgeben
  • Task<T> — für Methoden, die einen Wert vom Typ T zurückgeben
  • ValueTask<T> — für Szenarien mit hoher Leistung, bei denen das Ergebnis oft synchron verfügbar ist


// Ohne Rückgabewertpublic async Task SaveDataAsync(string data){    await File.WriteAllTextAsync("data.txt", data);}

// Mit Rückgabewertpublic async Task<int> CalculateSumAsync(int a, int b){ await Task.Delay(100); // Simulation einer langwierigen Operation return a + b;}

// ValueTask für Optimierungpublic async ValueTask<bool> CheckCacheAsync(string key){ if (_cache.ContainsKey(key)) return true; await Task.Delay(50); return false;}


Fortgeschrittene Arbeit mit Task



Die Klasse Task ist die Grundlage der asynchronen Programmierung in C#. Betrachten wir die nützlichsten Methoden und Muster.



Parallele Ausführung von Aufgaben



Die Methoden Task.WhenAll und Task.WhenAny ermöglichen eine effiziente Verwaltung mehrerer asynchroner Operationen.



public async Task ProcessMultipleRequestsAsync(){    var task1 = FetchDataAsync("url1");    var task2 = FetchDataAsync("url2");    var task3 = FetchDataAsync("url3");        // Warten auf den Abschluss aller Aufgaben    await Task.WhenAll(task1, task2, task3);        Console.WriteLine("Alle Anfragen abgeschlossen");}

public async Task<string> GetFirstResponseAsync(){ var task1 = FetchDataAsync("url1"); var task2 = FetchDataAsync("url2"); // Warten auf die erste abgeschlossene Aufgabe Task<string> completedTask = await Task.WhenAny(task1, task2); return await completedTask;}


Abbruch asynchroner Operationen

Blogs

Buchempfehlungen