15.4 Asynchrone Programmierung mit »async« und »await«
In den Abschnitten 15.2.12 bis 15.2.14 haben wir uns mit den asynchronen Aufrufen von Methoden auseinandergesetzt. Mit dem .NET Framework 4.5 wurde eine weitere, gänzlich neue Variante eingeführt. Diese soll dabei helfen, asynchrone Operationen einfacher auszuführen. Dazu wurden zwei neue Schlüsselwörter für C# ins Spiel gebracht: async und await.
Ehe ich Ihnen die Zusammenhänge erläutere, möchte ich ein kleines Beispiel vorstellen.
// Beispiel: ..\Kapitel 15\AwaitSample
class Program
{
static void Main(string[] args)
{
DoSomethingAsync();
for (int i = 0; i < 1000; i++)
Console.Write(".");
Console.ReadLine();
}
static async void DoSomethingAsync()
{
Console.Write("Start");
Console.Write(await TestAsync());
}
static async Task<string> TestAsync()
{
await Task.Delay(20);
return "Fertig";
}
}
Listing 15.30 Aufruf einer »async«-Methode
Das Resultat des Aufrufs sehen Sie in Abbildung 15.11.
Abbildung 15.11 Ausgabe des Beispielprogramms »AwaitSample«
Bei der asynchron aufgerufenen Methode handelt es sich hier um TestAsync. Diese Methode ist mit dem in .NET 4.5 neu eingeführten Modifikator async gekennzeichnet. Um eine länger andauernde Aufgabe zu simulieren, wird innerhalb der Methode TestAsync mit Task.Delay eine Verzögerung von zwei Sekunden erzwungen. Mit async gekennzeichnete Methoden ermöglichen einem Aufrufer, seine Arbeit fortzusetzen. Er wird also nicht blockiert. Üblicherweise erhalten solche Methoden auch das Suffix Async.
Im .NET Framework 4.5 wurden zahlreichen Methoden eingeführt, die dem neuen Async-Pattern entsprechen. Die Klassen, die um solche Methoden erweitert worden sind, können hauptsächlich den Bereichen Internetzugriff, dem Lesen und Schreiben von Dateien und dem Laden von Images zugeordnet werden. Eine der typischen, neuen Methoden ist zum Beispiel GetStringAsync der Klasse HttpClient. Unsere Methode TestAsync soll nur eine der neuen asynchron operierenden Methoden des Frameworks vertreten.
async-Methoden haben einen vorgeschriebenen Rückgabewert. Er ist entweder void oder liefert den Typ Task oder Task<TResult> zurück. Unsere Stellvertretermethode TestAsync liefert Task<string> zurück. Beachten Sie dabei bitte, dass die Rückgabe mit return innerhalb der Methode tatsächlich den Typ string bereitstellt. Auch die Parameter einer async-Methode unterliegen einer Einschränkung: Sie dürfen nämlich weder ref noch out sein.
Aufgerufen wird TestAsync aus der Methode DoSomethingAsync heraus. Dabei kommt auch der neue Operator await ins Spiel. Die Aufgabe von await ist zu warten, bis der angegebene Task fertig ist. Dennoch kann der Aufrufer mit den darauf folgenden Anweisungen den Programmablauf fortsetzen, ohne blockiert zu sein.
Im Grunde genommen hätten wir auch auf DoSomethingAsync verzichten können und deren Programmcode direkt in Main codieren können. Allerdings hätten wir dann Main mit async signieren müssen, was für den Einstiegspunkt in eine Anwendung nicht erlaubt ist. Andererseits können aber Ereignishandler durchaus mit async spezifiziert werden, was dann natürlich besonders bei Anwendungen mit einer grafischen Benutzeroberfläche wieder sehr interessant wird.
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.