Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Använd funktionen Async för att komma åt filer. Med hjälp av funktionen Async kan du anropa till asynkrona metoder utan att använda motringningar eller dela upp koden mellan flera metoder eller lambda-uttryck. Om du vill göra synkron kod asynkron anropar du en asynkron metod i stället för en synkron metod och lägger till några nyckelord i koden.
Överväg att lägga till asynkron till filåtkomstanrop av följande skäl:
Asynkron gör UI-program mer dynamiska eftersom användargränssnittstråden som startar åtgärden kan utföra annat arbete. Om användargränssnittstråden måste köra kod som tar lång tid (till exempel mer än 50 millisekunder) kan användargränssnittet låsas tills I/O har slutförts och användargränssnittstråden kan bearbeta tangentbords- och musindata och andra händelser igen.
Asynkron förbättrar skalbarheten för ASP.NET och andra serverbaserade program genom att minska behovet av trådar. Om programmet använder en dedikerad tråd per svar och tusen begäranden hanteras samtidigt behövs tusen trådar. Asynkrona åtgärder behöver ofta inte använda en tråd under väntan. De använder den befintliga I/O-slutförandetråden en kort stund i slutet.
Svarstiden för en filåtkomståtgärd kan vara mycket låg under aktuella förhållanden, men svarstiden kan öka avsevärt i framtiden. En fil kan till exempel flyttas till en server som finns över hela världen.
Den extra kostnaden för att använda Async-funktionen är liten.
Flera asynkrona I/O-åtgärder kan köras utan att blockera den anropande tråden.
Kör exemplen
Om du vill köra exemplen i det här avsnittet skapar du ett WPF-program eller ett Windows Forms-program och lägger sedan till en knapp. I knappens Click händelse lägger du till ett anrop till den första metoden i varje exempel.
I de kommande exemplen, ta med följande Imports instruktioner.
Imports System
Imports System.Collections.Generic
Imports System.Diagnostics
Imports System.IO
Imports System.Text
Imports System.Threading.Tasks
Användning av klassen FileStream
Exemplen FileStream i det här avsnittet använder klassen, som har ett alternativ som gör att asynkron I/O inträffar på operativsystemnivå. Med det här alternativet kan du undvika att blockera en ThreadPool-tråd i många fall. Om du vill aktivera det här alternativet anger du useAsync=true argumentet eller options=FileOptions.Asynchronous i konstruktoranropet.
Du kan inte använda det här alternativet med StreamReader och StreamWriter om du öppnar dem direkt genom att ange en filsökväg. Du kan dock använda det här alternativet om du ger dem ett Stream som klassen FileStream öppnade. Asynkrona anrop går snabbare i användargränssnittsappar även om en ThreadPool-tråd blockeras, eftersom användargränssnittstråden inte blockeras under väntetiden.
Skriva text
I följande exempel skrivs text till en fil. Vid varje await-instruktion avslutas metoden omedelbart. När fil-I/O är klar återupptas metoden vid instruktionen som följer inväntningsuttryck. Asynkron modifieraren finns i definitionen av metoder som använder await-instruktionen.
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
Det ursprungliga exemplet har -instruktionen Await sourceStream.WriteAsync(encodedText, 0, encodedText.Length), som är en kontraktion av följande två instruktioner:
Dim theTask As Task = sourceStream.WriteAsync(encodedText, 0, encodedText.Length)
Await theTask
Den första instruktionen returnerar en uppgift och gör att filbearbetningen startar. Den andra instruktionen med await orsakar att metoden omedelbart avslutas och returnerar en annan uppgift. När filbearbetningen senare slutförs återgår körningen till den instruktion som följer väntan. Mer information finns i Kontrollera flöde i Async-program (Visual Basic).
Läsa text
I följande exempel läss text från en fil. Texten buffras och placeras i det här fallet i en StringBuilder. Till skillnad från i föregående exempel genererar utvärderingen av await ett värde. Metoden ReadAsync returnerar en Task<Int32>, så utvärderingen av await genererar ett Int32 värde (numRead) när åtgärden har slutförts. Mer information finns i Async Return Types (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
Flera asynkrona I/O-åtgärder
I följande exempel startas flera asynkrona skrivåtgärder. Runtime-miljön köar dessa åtgärder, och den underliggande implementeringen kan använda asynkron I/O i operativsystem eller trådar i trådpooler beroende på plattform och konfiguration, därför beror faktisk samtidighet på operativsystem och maskinvara. För varje fil WriteAsync returnerar metoden en uppgift som läggs till i en lista över aktiviteter. Uttalandet Await Task.WhenAll(tasks) avslutar metoden och fortsätter inom metoden när bearbetningen av filerna är klar för alla uppgifter.
Exemplet stänger alla FileStream instanser i ett Finally block när uppgifterna har slutförts. Om varje FileStream i stället skapas i en Using-instruktion kan FileStream frigöras innan uppgiften har slutförts.
Det asynkrona tillvägagångssättet undviker att blockera den anropande tråden medan I/O-händelsen pågår. I många fall beror dataflödesförbättringar på operativsystemet, maskinvaran och, på vissa plattformar, .NET-körningsbeteende, till exempel begränsningar för trådpooler och schemaläggning.
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
När du använder metoderna WriteAsync och ReadAsync, kan du ange en CancellationToken för att avbryta åtgärden under processen. Mer information finns iFine-Tuning Ditt Async-program (Visual Basic) och Annullering i hanterade trådar.