Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Verwenden Sie das Async-Feature, um auf Dateien zuzugreifen. Mithilfe des Async-Features können Sie asynchrone Methoden aufrufen, ohne Rückrufe zu verwenden oder den Code auf mehrere Methoden oder Lambda-Ausdrücke aufzuteilen. Um synchronen Code asynchron zu machen, rufen Sie eine asynchrone Methode anstelle einer synchronen Methode auf, und fügen Sie dem Code einige Schlüsselwörter hinzu.
Erwägen Sie das Hinzufügen einer Asynchronität zu Dateizugriffsaufrufen aus folgenden Gründen:
Asynchrony macht UI-Anwendungen reaktionsfähiger, da der UI-Thread, der den Vorgang startet, andere Aufgaben ausführen kann. Wenn der UI-Thread Code ausführen muss, der lange dauern muss (z. B. mehr als 50 Millisekunden), kann die Benutzeroberfläche eingefroren werden, bis die E/A abgeschlossen ist, und der UI-Thread kann die Tastatur- und Mauseingabe und andere Ereignisse erneut verarbeiten.
Asynchrony verbessert die Skalierbarkeit von ASP.NET und anderen serverbasierten Anwendungen, indem die Notwendigkeit von Threads reduziert wird. Wenn die Anwendung pro Antwort einen dedizierten Thread verwendet und tausend Anforderungen gleichzeitig verarbeitet werden, werden tausend Threads benötigt. Asynchrone Vorgänge müssen während der Wartezeit häufig keinen Thread verwenden. Sie verwenden den vorhandenen E/A-Abschlussthread kurz am Ende.
Die Latenz eines Dateizugriffsvorgangs kann unter aktuellen Bedingungen sehr niedrig sein, die Latenz kann sich jedoch in Zukunft erheblich erhöhen. Beispielsweise kann eine Datei auf einen Server verschoben werden, der sich auf der ganzen Welt befindet.
Der zusätzliche Aufwand für die Verwendung des Async-Features ist klein.
Mehrere asynchrone E/A-Vorgänge können ausgeführt werden, ohne den aufrufenden Thread zu blockieren.
Führen Sie die Beispiele aus
Um die Beispiele in diesem Thema auszuführen, erstellen Sie eine WPF-Anwendung oder eine Windows Forms-Anwendung , und fügen Sie dann eine Schaltfläche hinzu. Fügen Sie im Ereignis der Schaltfläche Click in jedem Beispiel einen Aufruf der ersten Methode hinzu.
Nehmen Sie in den folgenden Beispielen die Imports-Anweisungen mit auf.
Imports System
Imports System.Collections.Generic
Imports System.Diagnostics
Imports System.IO
Imports System.Text
Imports System.Threading.Tasks
Verwendung der FileStream-Klasse
In den Beispielen in diesem Thema wird die FileStream Klasse verwendet, die über eine Option verfügt, die dazu führt, dass asynchrone E/A-Vorgänge auf Betriebssystemebene auftreten. Mit dieser Option können Sie in vielen Fällen verhindern, dass ein ThreadPool-Thread blockiert wird. Um diese Option zu aktivieren, geben Sie das useAsync=true Oder-Argument options=FileOptions.Asynchronous im Konstruktoraufruf an.
Sie können diese Option nicht mit StreamReader und StreamWriter verwenden, wenn Sie diese direkt öffnen, indem Sie einen Dateipfad angeben. Allerdings können Sie diese Option verwenden, wenn Sie ihnen ein Stream geben, das die FileStream-Klasse geöffnet hat. Asynchrone Aufrufe sind in UI-Apps schneller, auch wenn ein ThreadPool-Thread blockiert wird, da der UI-Thread während der Wartezeit nicht blockiert wird.
Text schreiben
Im folgenden Beispiel wird Text in eine Datei geschrieben. Bei jeder await-Anweisung wird die Methode sofort beendet. Wenn die Datei-E/A abgeschlossen ist, wird die Methode bei der Anweisung hinter der await-Anweisung fortgesetzt. Der asynchrone Modifizierer befindet sich in der Definition von Methoden, die die Await-Anweisung verwenden.
Public Async Sub ProcessWrite()
Dim filePath = "temp2.txt"
Dim text = "Hello World" & ControlChars.CrLf
Await WriteTextAsync(filePath, text)
End Sub
Private Async Function WriteTextAsync(filePath As String, text As String) As Task
Dim encodedText As Byte() = Encoding.Unicode.GetBytes(text)
Using sourceStream As New FileStream(filePath,
FileMode.Append, FileAccess.Write, FileShare.None,
bufferSize:=4096, useAsync:=True)
Await sourceStream.WriteAsync(encodedText, 0, encodedText.Length)
End Using
End Function
Das ursprüngliche Beispiel weist die Anweisung Await sourceStream.WriteAsync(encodedText, 0, encodedText.Length)auf, die eine Kontraktion der folgenden beiden Anweisungen ist:
Dim theTask As Task = sourceStream.WriteAsync(encodedText, 0, encodedText.Length)
Await theTask
Die erste Anweisung gibt eine Aufgabe zurück und bewirkt, dass die Dateiverarbeitung gestartet wird. Die zweite await-Anweisung führt dazu, dass die Methode sofort beendet wird und eine andere Aufgabe zurückgibt. Wenn die Dateiverarbeitung später abgeschlossen wird, wird die Ausführung bei der Anweisung fortgesetzt, die auf die „await“-Anweisung folgt. Weitere Informationen finden Sie unter Steuerungsfluss in asynchronen Programmen (Visual Basic).
Lesen von Text
Im folgenden Beispiel wird Text aus einer Datei gelesen. Der Text wird zwischengespeichert und in diesem Fall in ein StringBuilder eingefügt. Im Gegensatz zum vorherigen Beispiel erzeugt die Auswertung des Await einen Wert. Die ReadAsync Methode gibt eine Task<Int32> zurück, sodass die Auswertung des Await einen Int32 Wert (numRead) nach Abschluss des Vorgangs erzeugt. Weitere Informationen finden Sie unter Asynchrone Rückgabetypen (Visual Basic).
Public Async Sub ProcessRead()
Dim filePath = "temp2.txt"
If File.Exists(filePath) = False Then
Debug.WriteLine("file not found: " & filePath)
Else
Try
Dim text As String = Await ReadTextAsync(filePath)
Debug.WriteLine(text)
Catch ex As Exception
Debug.WriteLine(ex.Message)
End Try
End If
End Sub
Private Async Function ReadTextAsync(filePath As String) As Task(Of String)
Using sourceStream As New FileStream(filePath,
FileMode.Open, FileAccess.Read, FileShare.Read,
bufferSize:=4096, useAsync:=True)
Dim sb As New StringBuilder
Dim buffer As Byte() = New Byte(&H1000) {}
Dim numRead As Integer
numRead = Await sourceStream.ReadAsync(buffer, 0, buffer.Length)
While numRead <> 0
Dim text As String = Encoding.Unicode.GetString(buffer, 0, numRead)
sb.Append(text)
numRead = Await sourceStream.ReadAsync(buffer, 0, buffer.Length)
End While
Return sb.ToString
End Using
End Function
Mehrere asynchrone E/A-Vorgänge
Im folgenden Beispiel werden mehrere asynchrone Schreibvorgänge gestartet. Die Laufzeit reiht diese Vorgänge in Warteschlangen ein und die zugrunde liegende Implementierung verwendet je nach Plattform und Konfiguration möglicherweise asynchrone E/A- oder Threadpool-Threads, womit die tatsächliche Parallelität von der Betriebssystemplattform und der Hardware abhängt. Für jede Datei gibt die WriteAsync Methode eine Aufgabe zurück, die einer Aufgabenliste hinzugefügt wird. Die Await Task.WhenAll(tasks) Anweisung beendet die Methode und setzt die Ausführung innerhalb der Methode fort, sobald die Dateiverarbeitung für alle Aufgaben abgeschlossen ist.
Im Beispiel werden alle FileStream Instanzen in einem Finally Block geschlossen, nachdem die Aufgaben abgeschlossen wurden. Wenn jedes FileStream stattdessen in einer Using-Anweisung erstellt wurde, könnte die FileStream möglicherweise freigegeben werden, bevor die Aufgabe abgeschlossen ist.
Der asynchrone Ansatz verhindert, dass der aufrufende Thread blockiert wird, während E/A aussteht. In vielen Fällen hängen Durchsatzverbesserungen vom Betriebssystem, der Hardware und auf einigen Plattformen vom .NET-Laufzeitverhalten ab, z. B. Threadpoolbeschränkungen und -planung.
Public Async Sub ProcessWriteMult()
Dim folder = "tempfolder\"
Dim tasks As New List(Of Task)
Dim sourceStreams As New List(Of FileStream)
Try
For index = 1 To 10
Dim text = "In file " & index.ToString & ControlChars.CrLf
Dim fileName = "thefile" & index.ToString("00") & ".txt"
Dim filePath = folder & fileName
Dim encodedText As Byte() = Encoding.Unicode.GetBytes(text)
Dim sourceStream As New FileStream(filePath,
FileMode.Append, FileAccess.Write, FileShare.None,
bufferSize:=4096, useAsync:=True)
Dim theTask As Task = sourceStream.WriteAsync(encodedText, 0, encodedText.Length)
sourceStreams.Add(sourceStream)
tasks.Add(theTask)
Next
Await Task.WhenAll(tasks)
Finally
For Each sourceStream As FileStream In sourceStreams
sourceStream.Close()
Next
End Try
End Sub
Wenn Sie die WriteAsync- und ReadAsync-Methoden verwenden, können Sie ein CancellationToken angeben, um den Vorgang während der Ausführung abzubrechen. Weitere Informationen finden Sie unter Fine-Tuning Ihrer asynchronen Anwendung (Visual Basic) und Abbruch in verwalteten Threads.
Siehe auch
- Asynchrone Programmierung mit „Async“ und „Await“ (Visual Basic)
- Async Return Types (Visual Basic) (Asynchrone Rückgabetypen (Visual Basic))
- Steuerungsfluss in Async-Programmen (Visual Basic)