Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Vous pouvez utiliser la fonctionnalité asynchrone pour accéder aux fichiers. À l’aide de la fonctionnalité asynchrone, vous pouvez appeler des méthodes asynchrones sans utiliser de rappels ou fractionner votre code entre plusieurs méthodes ou expressions lambda. Pour rendre le code synchrone asynchrone, vous appelez simplement une méthode asynchrone au lieu d’une méthode synchrone et ajoutez quelques mots clés au code.
Vous pouvez prendre en compte les raisons suivantes d’ajouter une synchronisation aux appels d’accès aux fichiers :
Asynchrony rend les applications d’interface utilisateur plus réactives, car le thread d’interface utilisateur qui lance l’opération peut effectuer d’autres tâches. Si le thread d’interface utilisateur doit exécuter du code qui prend beaucoup de temps (par exemple, plus de 50 millisecondes), l’interface utilisateur peut se figer jusqu’à ce que l’E/S soit terminée et que le thread d’interface utilisateur puisse à nouveau traiter l’entrée du clavier et de la souris et d’autres événements.
Asynchrony améliore la scalabilité des ASP.NET et d’autres applications basées sur le serveur en réduisant le besoin de threads. Si l’application utilise un thread dédié par réponse et qu’un millier de requêtes sont traitées simultanément, un millier de threads sont nécessaires. Les opérations asynchrones n’ont souvent pas besoin d’utiliser un thread pendant l’attente. Elles utilisent le thread de terminaison d’E/S existant brièvement à la fin.
La latence d’une opération d’accès aux fichiers peut être très faible dans les conditions actuelles, mais la latence peut augmenter considérablement à l’avenir. Par exemple, un fichier peut être déplacé vers un serveur qui se trouve dans le monde entier.
La surcharge ajoutée de l’utilisation de la fonctionnalité asynchrone est petite.
Les tâches asynchrones peuvent facilement être exécutées en parallèle.
Exécution des exemples
Pour exécuter les exemples de cette rubrique, vous pouvez créer une application WPF ou une application Windows Forms , puis ajouter un bouton. Dans l’événement du bouton Click
, ajoutez un appel à la première méthode dans chaque exemple.
Dans les exemples suivants, incluez les déclarations suivantes Imports
.
Imports System
Imports System.Collections.Generic
Imports System.Diagnostics
Imports System.IO
Imports System.Text
Imports System.Threading.Tasks
Utilisation de la classe FileStream
Les exemples de cette rubrique utilisent la FileStream classe, qui a une option qui entraîne l’exécution d’E/S asynchrones au niveau du système d’exploitation. En utilisant cette option, vous pouvez éviter de bloquer un thread ThreadPool dans de nombreux cas. Pour activer cette option, vous spécifiez l’argument useAsync=true
ou l’argument options=FileOptions.Asynchronous
dans l’appel du constructeur.
Vous ne pouvez pas utiliser cette option avec StreamReader et StreamWriter si vous les ouvrez directement en spécifiant un chemin d’accès au fichier. Toutefois, vous pouvez utiliser cette option si vous leur fournissez un Stream ouvert par la classe FileStream. Notez que les appels asynchrones sont plus rapides dans les applications d’interface utilisateur même si un thread ThreadPool est bloqué, car le thread d’interface utilisateur n’est pas bloqué pendant l’attente.
Écriture de texte
L’exemple suivant écrit du texte dans un fichier. À chaque instruction await, la méthode s'arrête immédiatement. Quand l’E/S de fichier est terminée, la méthode reprend à l’instruction qui suit l’instruction await. Notez que le modificateur asynchrone se trouve dans la définition de méthodes qui utilisent l’instruction await.
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 a l’instruction Await sourceStream.WriteAsync(encodedText, 0, encodedText.Length)
, qui est une contraction des deux instructions suivantes :
Dim theTask As Task = sourceStream.WriteAsync(encodedText, 0, encodedText.Length)
Await theTask
La première instruction retourne une tâche et provoque le démarrage du traitement des fichiers. La deuxième instruction avec await provoque la fin immédiate de la méthode et retourne une tâche différente. Quand le traitement du fichier se termine plus loin, l’exécution retourne à l’instruction qui suit l’attente. Pour plus d’informations, consultez Control Flow in Async Programs (Visual Basic).
Lecture de texte
L’exemple suivant lit du texte à partir d’un fichier. Le texte est mis en mémoire tampon et, dans cet exemple, est placé dans un StringBuilder. Contrairement à l’exemple précédent, l’évaluation de l’instruction await génère une valeur. La méthode ReadAsync retourne un Task<Int32>, de sorte que l’évaluation de l'await produit une Int32
valeur (numRead
) une fois l’opération terminée. Pour plus d’informations, consultez Types de retour asynchrones (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èle
L’exemple suivant illustre le traitement parallèle en écrivant 10 fichiers texte. Pour chaque fichier, la WriteAsync méthode retourne une tâche qui est ensuite ajoutée à une liste de tâches. L’instruction Await Task.WhenAll(tasks)
quitte la méthode et reprend dans la méthode lorsque le traitement du fichier est terminé pour toutes les tâches.
L’exemple ferme toutes les FileStream instances d’un Finally
bloc une fois les tâches terminées. Si chaque FileStream
était créé dans une instruction Imports
, le FileStream
pourrait être supprimé avant la fin de la tâche.
Notez que toute amélioration des performances provient presque entièrement du traitement parallèle et non du traitement asynchrone. Les avantages de l’asynchronie sont qu’il ne lie pas plusieurs threads, et qu’il ne lie pas le thread d’interface utilisateur.
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
Lorsque vous utilisez les méthodes WriteAsync et ReadAsync, vous pouvez spécifier un CancellationToken que vous pouvez utiliser pour annuler l'opération en cours. Pour plus d’informations, consultez Fine-Tuning Votre application asynchrone (Visual Basic) et l’annulation dans les threads managés.