Megosztás a következőn keresztül:


Az Async használata fájlhozzáféréshez (Visual Basic)

Az Async funkcióval elérheti a fájlokat. Az Async funkcióval visszahívások nélkül hívhat be aszinkron metódusokat, vagy feloszthatja a kódot több metódusra vagy lambdakifejezésre. A szinkron kód aszinkronvá alakításához csak egy aszinkron metódust hívhat meg szinkron metódus helyett, és adjon hozzá néhány kulcsszót a kódhoz.

Megfontolhatja az aszinkron fájlelérési hívásokhoz való aszinkronizálás hozzáadásának következő okait:

  • Az aszinkronizálás rugalmasabbá teszi a felhasználói felületi alkalmazásokat, mert a műveletet megnyitó felhasználói felületi szál más műveleteket is végrehajthat. Ha a felhasználói felületi szálnak olyan kódot kell végrehajtania, amely hosszabb időt vesz igénybe (például több mint 50 ezredmásodpercet), a felhasználói felület lefagyhat, amíg az I/O be nem fejeződik, és a felhasználói felület szála újra feldolgozhatja a billentyűzet- és egérbemenetet és egyéb eseményeket.

  • Az aszinkronizálás javítja a ASP.NET és más kiszolgálóalapú alkalmazások méretezhetőségét azáltal, hogy csökkenti a szálak szükségességét. Ha az alkalmazás válaszonként dedikált szálat használ, és egyszerre ezer kérést kezelnek, ezer szálra van szükség. Az aszinkron műveleteknek gyakran nem kell szálat használniuk a várakozás során. A meglévő I/O-befejezési szálat rövid időre használják a végén.

  • A fájlelérési művelet késése a jelenlegi körülmények között nagyon alacsony lehet, de a késés a jövőben jelentősen megnőhet. Előfordulhat például, hogy egy fájl átkerül egy olyan kiszolgálóra, amely a világ minden részén található.

  • Az Async szolgáltatás használatának többletterhelése kicsi.

  • Az aszinkron feladatok egyszerűen futtathatók párhuzamosan.

A példák futtatása

A jelen témakörben szereplő példák futtatásához létrehozhat egy WPF-alkalmazást vagy egy Windows Forms-alkalmazást , majd hozzáadhat egy gombot. A gomb eseményében Click adjon hozzá egy hívást az egyes példák első metódusához.

Az alábbi példákban adja meg az alábbi Imports utasításokat.

Imports System  
Imports System.Collections.Generic  
Imports System.Diagnostics  
Imports System.IO  
Imports System.Text  
Imports System.Threading.Tasks  

A FileStream-osztály használata

A jelen témakörben szereplő példák az FileStream osztályt használják, amely az aszinkron I/O-t az operációs rendszer szintjén okozza. Ezzel a beállítással számos esetben elkerülheti a ThreadPool-szálak blokkolását. A beállítás engedélyezéséhez adja meg a useAsync=true konstruktorhívásban szereplő argumentumot vagy options=FileOptions.Asynchronous argumentumot.

Ezt a beállítást StreamReader nem használhatja közvetlenül egy fájl elérési útjának megadásával, és StreamWriter ha közvetlenül nyitja meg őket. Ezt a lehetőséget azonban akkor használhatja, ha megad nekik egy Stream , az FileStream osztály által megnyitottat. Vegye figyelembe, hogy az aszinkron hívások akkor is gyorsabbak a felhasználói felületen futó alkalmazásokban, ha egy ThreadPool-szál le van tiltva, mert a felhasználói felületi szál nem lesz blokkolva a várakozás során.

Szöveg írása

Az alábbi példa szöveget ír egy fájlba. Minden várakozási utasításnál a metódus azonnal kilép. A fájl I/O-jának befejezése után a metódus a várakozási utasítást követő utasításban folytatódik. Vegye figyelembe, hogy az aszinkron módosító a await utasítást használó metódusok definíciójában szerepel.

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  

Az eredeti példában az utasítás Await sourceStream.WriteAsync(encodedText, 0, encodedText.Length)szerepel, amely a következő két utasítás összevonása:

Dim theTask As Task = sourceStream.WriteAsync(encodedText, 0, encodedText.Length)  
Await theTask  

Az első utasítás egy feladatot ad vissza, és elindítja a fájlfeldolgozást. A második várakozási utasítás hatására a metódus azonnal kilép, és egy másik feladatot ad vissza. Amikor a fájlfeldolgozás később befejeződik, a végrehajtás visszatér a várakozást követő utasításhoz. További információ: Control Flow in Async Programs (Visual Basic).

Szöveg olvasása

Az alábbi példa egy fájlból olvas be szöveget. A szöveg pufferelve van, és ebben az esetben egy StringBuilder. Az előző példától eltérően a várakozás kiértékelése értéket hoz létre. A ReadAsync metódus egyInt32<>Task értéket ad vissza, így a várakozás kiértékelése a művelet befejezése után egy Int32 értéket (numRead) eredményez. További információ: 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  

Párhuzamos Aszinkron I/O

Az alábbi példa 10 szövegfájl megírásával szemlélteti a párhuzamos feldolgozást. A metódus minden fájlhoz visszaad egy feladatot, WriteAsync amelyet aztán hozzáad a tevékenységek listájához. Az Await Task.WhenAll(tasks) utasítás kilép a metódusból, és folytatódik a metóduson belül, amikor a fájlfeldolgozás befejeződött az összes feladat esetében.

A példa egy blokk összes FileStream példányát Finally bezárja a tevékenységek befejezése után. Ha ehelyett egy FileStreamImports utasításban hozták létre őket, a FileStream művelet befejezése előtt a rendszer elvetheti őket.

Vegye figyelembe, hogy a teljesítménynövelés szinte teljesen a párhuzamos feldolgozásból származik, nem pedig az aszinkron feldolgozásból. Az aszinkronizálás előnye, hogy nem köt össze több szálat, és nem köti össze a felhasználói felület szálát.

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  

A metódusok és ReadAsync a WriteAsync metódusok használatakor megadhatja CancellationTokena műveletet a stream közbeni megszakításhoz. További információ: Az Async-alkalmazás (Visual Basic) és a lemondás finomhangolása felügyelt szálakban.

Lásd még