Utilisation d’async pour l’accès aux fichiers (Visual Basic)Using Async for File Access (Visual Basic)

Vous pouvez utiliser la fonctionnalité Async pour accéder aux fichiers.You can use the Async feature to access files. La fonctionnalité Async vous permet d’appeler des méthodes asynchrones sans utiliser de rappels ni fractionner votre code entre plusieurs méthodes ou expressions lambda.By using the Async feature, you can call into asynchronous methods without using callbacks or splitting your code across multiple methods or lambda expressions. Pour rendre le code synchrone asynchrone, il vous suffit d’appeler une méthode asynchrone au lieu d’une méthode synchrone, puis d’ajouter quelques mots clés au code.To make synchronous code asynchronous, you just call an asynchronous method instead of a synchronous method and add a few keywords to the code.

Vous pouvez considérer les raisons suivantes pour ajouter de l'asynchrone aux appels d'accès aux fichiers :You might consider the following reasons for adding asynchrony to file access calls:

  • L'asynchronisme rend les applications d'interface utilisateur plus réactives parce que le thread d'interface utilisateur qui lance l'exécution peut effectuer d'autres tâches.Asynchrony makes UI applications more responsive because the UI thread that launches the operation can perform other work. Si le thread d’interface utilisateur doit exécuter du code qui prend du temps (par exemple, plus de 50 millisecondes), l’interface utilisateur peut figer jusqu’à ce que l’E/S soit terminée et que le thread d’interface utilisateur puisse traiter à nouveau des entrées au clavier et à la souris et d’autres événements.If the UI thread must execute code that takes a long time (for example, more than 50 milliseconds), the UI may freeze until the I/O is complete and the UI thread can again process keyboard and mouse input and other events.

  • L'asynchronisme améliore l'extensibilité d'ASP.NET et d'autres applications serveur en réduisant le besoin de threads.Asynchrony improves the scalability of ASP.NET and other server-based applications by reducing the need for threads. Si l'application utilise un thread dédié par réponse et que mille demandes sont traitées simultanément, mille threads sont nécessaires.If the application uses a dedicated thread per response and a thousand requests are being handled simultaneously, a thousand threads are needed. Les opérations asynchrones n'ont souvent pas besoin d'utiliser un thread pendant l'attente.Asynchronous operations often don’t need to use a thread during the wait. Elles utilisent le thread de terminaison d’E/S existant brièvement à la fin.They use the existing I/O completion thread briefly at the end.

  • La latence d'une opération d'accès à un fichier peut être très basse sous les conditions actuelles, mais la latence peut considérablement augmenter à l'avenir.The latency of a file access operation might be very low under current conditions, but the latency may greatly increase in the future. Par exemple, un fichier peut être déplacé vers un serveur qui se trouve à travers le monde.For example, a file may be moved to a server that's across the world.

  • La charge mémoire supplémentaire pour l'utilisation de la fonctionnalité Async est faible.The added overhead of using the Async feature is small.

  • Les tâches asynchrones peuvent facilement être exécutées en parallèle.Asynchronous tasks can easily be run in parallel.

Exécution des exemplesRunning the Examples

Pour exécuter les exemples de cette rubrique, vous pouvez créer une application WPF ou une application Windows Forms, puis ajouter un bouton.To run the examples in this topic, you can create a WPF Application or a Windows Forms Application and then add a Button. Dans l’événement Click du bouton, ajoutez un appel à la première méthode de chaque exemple.In the button's Click event, add a call to the first method in each example.

Dans les exemples qui suivent, incluez les instructions Imports suivantes.In the following examples, include the following Imports statements.

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

Utilisation de la classe FileStreamUse of the FileStream Class

Les exemples de cette rubrique utilisent la classe FileStream, avec une option qui provoque une E/S asynchrone au niveau du système d’exploitation.The examples in this topic use the FileStream class, which has an option that causes asynchronous I/O to occur at the operating system level. En utilisant cette option, vous pouvez éviter de bloquer un thread de ThreadPool dans de nombreux cas.By using this option, you can avoid blocking a ThreadPool thread in many cases. Pour l’activer, spécifiez l’argument useAsync=true ou options=FileOptions.Asynchronous dans l’appel de constructeur.To enable this option, you specify the useAsync=true or options=FileOptions.Asynchronous argument in the constructor call.

Vous ne pouvez pas utiliser cette option avec StreamReader et StreamWriter si vous les ouvrez directement en spécifiant un chemin de fichier.You can’t use this option with StreamReader and StreamWriter if you open them directly by specifying a file path. Toutefois, vous pouvez utiliser cette option si vous leur fournissez un Stream ouvert par la classe FileStream.However, you can use this option if you provide them a Stream that the FileStream class opened. Notez que les appels asynchrones sont plus rapides dans des applications d’interface utilisateur même si un thread du ThreadPool est bloqué, car le thread d’interface utilisateur n’est pas bloqué pendant l’attente.Note that asynchronous calls are faster in UI apps even if a ThreadPool thread is blocked, because the UI thread isn’t blocked during the wait.

Écriture de texteWriting Text

L’exemple suivant écrit du texte dans un fichier.The following example writes text to a file. À chaque instruction await, la méthode s'arrête immédiatement.At each await statement, the method immediately exits. Quand l’E/S de fichier est terminée, la méthode reprend à l’instruction qui suit l’instruction await.When the file I/O is complete, the method resumes at the statement that follows the await statement. Notez que le modificateur async se trouve dans la définition des méthodes qui utilisent l'instruction await.Note that the async modifier is in the definition of methods that use the await statement.

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  

L’exemple d’origine comprend l’instruction Await sourceStream.WriteAsync(encodedText, 0, encodedText.Length), qui est une contraction des deux instructions suivantes :The original example has the statement Await sourceStream.WriteAsync(encodedText, 0, encodedText.Length), which is a contraction of the following two statements:

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

La première instruction retourne une tâche et provoque le début du traitement du fichier.The first statement returns a task and causes file processing to start. La deuxième instruction avec await provoque la fin immédiate de la méthode et retourne une tâche différente.The second statement with the await causes the method to immediately exit and return a different task. Quand le traitement du fichier se termine plus loin, l’exécution retourne à l’instruction qui suit l’attente.When the file processing later completes, execution returns to the statement that follows the await. Pour plus d’informations, consultez Control flow in Async Programs (Visual Basic).For more information, see Control Flow in Async Programs (Visual Basic).

Lecture de texteReading Text

L'exemple suivant lit du texte dans un fichier.The following example reads text from a file. Le texte est mis en mémoire tampon et, dans cet exemple, est placé dans un StringBuilder.The text is buffered and, in this case, placed into a StringBuilder. Contrairement à l’exemple précédent, l’évaluation de l’instruction await génère une valeur.Unlike in the previous example, the evaluation of the await produces a value. La méthode ReadAsync retourne un Task<Int32>, de sorte que l’évaluation de l’expression await génère une valeur Int32 (numRead) une fois l’opération effectuée.The ReadAsync method returns a Task<Int32>, so the evaluation of the await produces an Int32 value (numRead) after the operation completes. Pour plus d’informations, consultez types de retour Async (Visual Basic).For more information, see 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  

E/S asynchrones en parallèleParallel Asynchronous I/O

L’exemple suivant illustre le traitement en parallèle en écrivant 10 fichiers texte.The following example demonstrates parallel processing by writing 10 text files. Pour chaque fichier, la méthode WriteAsync retourne une tâche qui est ensuite ajoutée à une liste des tâches.For each file, the WriteAsync method returns a task that is then added to a list of tasks. L’instruction Await Task.WhenAll(tasks) quitte la méthode et reprend dans cette dernière quand le traitement du fichier est terminé pour toutes les tâches.The Await Task.WhenAll(tasks) statement exits the method and resumes within the method when file processing is complete for all of the tasks.

L’exemple ferme toutes les instances de FileStream dans un bloc Finally une fois les tâches effectuées.The example closes all FileStream instances in a Finally block after the tasks are complete. Si chaque FileStream était plutôt créé dans une instruction Imports, FileStream pourrait être libéré avant que la tâche ne soit terminée.If each FileStream was instead created in a Imports statement, the FileStream might be disposed of before the task was complete.

Notez que toutes les améliorations de performances sont presque entièrement dues au traitement parallèle et non au traitement asynchrone.Note that any performance boost is almost entirely from the parallel processing and not the asynchronous processing. Les avantages du mode asynchrone sont qu'il n'attache pas plusieurs threads et qu'il ne bloque pas le thread d'interface utilisateur.The advantages of asynchrony are that it doesn’t tie up multiple threads, and that it doesn’t tie up the user interface thread.

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  

Quand vous utilisez les méthodes WriteAsync et ReadAsync, vous pouvez spécifier un CancellationToken, qui vous permet d’annuler l’opération en cours de route.When using the WriteAsync and ReadAsync methods, you can specify a CancellationToken, which you can use to cancel the operation mid-stream. Pour plus d’informations, consultez réglage de votre application Async (Visual Basic) et annulation dans les threads managés.For more information, see Fine-Tuning Your Async Application (Visual Basic) and Cancellation in Managed Threads.

Voir aussiSee also