Neuigkeiten in der .NET-Klassenbibliothek, Teil 3: Asynchrone Methoden in IO-Klassen

Der Dotnet-Doktor  –  0 Kommentare

Die Version 4.5 der .NET-Framework-Klassenbibliothek enthält 947 neue Klassen. Eine Artikelserie stellt zehn Neuerungen vor, die nicht die großen Bibliotheken betreffen und daher nicht so im Licht der Öffentlichkeit stehen. Nachdem zuletzt Assembly-Metadaten vorgestellt wurden, geht es heute in Teil 3 um asynchrone Methoden in IO-Klassen.

Einige Klassen im Namensraum System.IO haben in .NET 4.5 neue asynchrone Methoden nach dem neuen Task-Entwurfsmuster als Pendant zu bestehenden synchronen Methoden bekommen. Alle diese Methoden liefern ein Task<Typ> zurück und lassen sich daher mit den neuen Schlüsselwörtern von C# und Visual Basic .NET async und await nutzen:

  • Klasse System.IO.Stream: ReadAsync(), WriteAsync(), FlushAsync(), CopyToAsync()
  • Klasse System.IO.TextReader (bzw. davon abgeleitete Klassen wie StreamReader): ReadAsync(), ReadBlockAsync(), ReadLineAsync(), ReadToEndAsync()
  • Klasse System.IO.TextWriter (bzw. davon abgeleitete Klassen wie StreamWriter): WriteAsync(), WriteLineAsync(), FlushAsync()

Microsoft hat dokumentiert, dass man sich bei einigen anderen IO-Klassen (z. B. BinaryReader und BinaryWriter) aktiv gegen eine Erweiterung um asynchrone Methoden entschieden hat.

Das folgende Beispiel zeigt das asynchrone Auslesen einer Datei mit ReadToEndAsync() in der Klasse StreamReader unter Einsatz von async und await.

public static void Run()
{
Console.WriteLine("Run() #1: Thread=" +
System.Threading.Thread.CurrentThread.ManagedThreadId);
ReadAsync();
Console.WriteLine("Run() #2: Thread=" +
System.Threading.Thread.CurrentThread.ManagedThreadId);
}

/// <summary>
/// Diese Methode startet das asynchrone Lesen
/// </summary>
/// <returns></returns>
public async static Task<string> ReadAsync()
{
string path = @"h:\temp\daten.txt";
string inhalt = "";
using (var sr = new System.IO.StreamReader(path))
{
inhalt = await sr.ReadToEndAsync(); // Hier wird die Kontrolle
// an den Aufrufer gegeben
// das Lesen erfolgt in eigenem Thread
}
// Der Rest der Methode wird auch in eigenem Thread abgearbeitet
Console.WriteLine("ReadAsync(): Thread=" +
System.Threading.Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("ReadAsync(): Länge des Inhalts=" +
inhalt.Length);
return inhalt;
}