Anteckning
Å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.
Du kan använda 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 bara en asynkron metod i stället för en synkron metod och lägger till några nyckelord i koden.
Du kan överväga följande orsaker till att lägga till asynkront i filåtkomstanrop:
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 frysas 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.
Asynkrona uppgifter kan enkelt köras parallellt.
Att köra exemplen
Om du vill köra exemplen i det här avsnittet kan du skapa ett WPF-program eller ett Windows Forms-program och sedan lägga 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 FileStream-klassen
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
eller options=FileOptions.Asynchronous
argumentet 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. Observera att 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. Observera att 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
Parallell asynkron I/O
I följande exempel visas parallell bearbetning genom att skriva 10 textfiler. För varje fil WriteAsync returnerar metoden en uppgift som sedan 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 skulle skapas i en Imports
-instruktion, kan FileStream
tas bort innan uppgiften har slutförts.
Observera att alla prestandaökningar nästan helt beror på parallell bearbetning och inte på asynkron bearbetning. Fördelarna med asynkron är att den inte binder upp flera trådar och att den inte binder upp användargränssnittstråden.
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, som du kan använda för att avbryta åtgärden under dess gång. Mer information finns iFine-Tuning Ditt Async-program (Visual Basic) och Annullering i hanterade trådar.