Utiliser Async pour l'accès aux fichiers (C# et Visual Basic)

Vous pouvez utiliser la fonctionnalité d' Async pour accéder aux fichiers. À l'aide de la fonctionnalité async, vous pouvez appeler des méthodes asynchrones sans utiliser des rappels ou fractionner votre code sur 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 des mots clés au code.

Vous pouvez considérer les raisons suivantes pour ajouter asynchrony des appels d'accès au fichier :

  • Asynchrony effectue des requêtes d'interface utilisateur plus réactives parce que le thread d'interface utilisateur qui lance l'exécution peut effectuer d'autres tâches. 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 terminée et le thread d'interface utilisateur peut encore traiter le clavier et l'entrée de la souris et d'autres événements.

  • Asynchrony améliore l'extensibilité ASP.NET et d'autres applications serveur en réduisant le besoin de threads. Si l'application utilise un thread dédié par réponse et pour mille " demandes sont traitées simultanément, mille threads sont nécessaires. Les opérations asynchrones souvent n'ont pas besoin d'utiliser un thread pendant l'attente. Ils utilisent le thread existant de terminaison d'E/S brièvement à la fin.

  • Latence d'une opération d'accès au fichier peut être des conditions actuelles de sous très insuffisantes, mais la latence peut considérablement augmenter à l'avenir. Par exemple, un fichier peut être déplacé vers un serveur qui exécute à travers le monde.

  • La charge mémoire supplémentaire d'utiliser la fonctionnalité Async est petite.

  • Les tâches asynchrones peuvent facilement être exécutées en parallèle.

Exécuter les exemples

Notes

Les exemples de cette rubrique ne s'appliquent pas à Windows Store les applications, qui sont des applications d' Windows 8 qui sont pleine page et adaptées pour l'interaction tactile.Pour plus d'informations sur l'utilisation de l'accès au fichier async dans des applications d' Windows Store , consultez Vue d'ensemble de .NET pour les applications Windows Store et le Fichier et flux de données E/S.Pour obtenir des exemples d'E/S de fichier pour les applications d' Windows Store , vous pouvez télécharger Exemple d'accès au fichier.

Pour exécuter les exemples de cette rubrique, vous pouvez créer Application WPF ou Application Windows Forms puis ajouter Bouton. Dans l'événement d' Click du bouton, ajoutez un appel à la première méthode dans chaque exemple.

Dans les exemples suivants, incluez Imports suivant (Visual Basic) ou les instructions d' using (C#).

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

Utilisation de la classe de FileStream

Les exemples de cette rubrique utilisent la classe d' FileStream , qui possède une option qui provoqué l'E/S asynchrones au niveau de le 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 d' useAsync=true ou d' options=FileOptions.Asynchronous dans l'appel de constructeur.

Vous ne pouvez pas utiliser cette option avec StreamReader et StreamWriter si vous l'ouvrez directement en spécifiant un chemin d'accès. Toutefois, vous pouvez utiliser cette option si vous leur fournissez Stream ce la classe d' FileStream ouverte. Notez que les appels asynchrones sont plus rapides dans des applications d'interface utilisateur même si un thread du pool est bloqué, car le thread d'interface utilisateur n'est pas bloqué lors de l'attente.

Écrire du texte

Le texte d'écritures d'exemple suivant dans un fichier. À chaque attendez que l'instruction, la méthode s'arrête immédiatement. Lorsque l'E/S de fichier est terminé, la méthode continue à l'instruction qui suit l'instruction d'attente. Notez que le modificateur async dans la définition des méthodes qui utilisent l'instruction d'attente.

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
public async void ProcessWrite()
{
    string filePath = @"temp2.txt";
    string text = "Hello World\r\n";

    await WriteTextAsync(filePath, text);
}

private async Task WriteTextAsync(string filePath, string text)
{
    byte[] encodedText = Encoding.Unicode.GetBytes(text);

    using (FileStream sourceStream = new FileStream(filePath,
        FileMode.Append, FileAccess.Write, FileShare.None,
        bufferSize: 4096, useAsync: true))
    {
        await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
    };
}

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
Task theTask = sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
await theTask;

La première instruction retourne une tâche et génère le fichier traitement pour démarrer. La deuxième instruction avec l'attente fait de quitter et retourner la méthode immédiatement une tâche différente. Lorsque le fichier traitement plus loin se termine, l'opération retourne à l'instruction qui suit l'attente. Pour plus d'informations, consultez Flux de contrôle dans les programmes Async (C# et Visual Basic) et Procédure pas à pas : utilisation du débogueur avec les méthodes Async.

Lire le texte

L'exemple suivant lit le texte à partir d'un fichier. Le texte est mis en mémoire tampon et, dans ce cas, placé dans StringBuilder. Contrairement à l'exemple précédent, l'évaluation de l'attente produit une valeur. La méthode d' ReadAsync retourne Task<Int32>, l'évaluation de l'attente produit une valeur d' Int32 (numRead) après que l'opération se termine. Pour plus d’informations, consultez Types de retour Async (C# et 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
public async void ProcessRead()
{
    string filePath = @"temp2.txt";

    if (File.Exists(filePath) == false)
    {
        Debug.WriteLine("file not found: " + filePath);
    }
    else
    {
        try
        {
            string text = await ReadTextAsync(filePath);
            Debug.WriteLine(text);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
    }
}

private async Task<string> ReadTextAsync(string filePath)
{
    using (FileStream sourceStream = new FileStream(filePath,
        FileMode.Open, FileAccess.Read, FileShare.Read,
        bufferSize: 4096, useAsync: true))
    {
        StringBuilder sb = new StringBuilder();

        byte[] buffer = new byte[0x1000];
        int numRead;
        while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
        {
            string text = Encoding.Unicode.GetString(buffer, 0, numRead);
            sb.Append(text);
        }

        return sb.ToString();
    }
}

E/S asynchrones en parallèle

L'exemple suivant montre le traitement en parallèle en écrivant 10 fichiers texte. Pour chaque fichier, la méthode d' WriteAsync retourne une tâche qui est alors ajoutée à la liste des tâches. L'instruction d' await Task.WhenAll(tasks); quitte la méthode et continue dans la méthode lorsque le traitement de fichier est complet pour toutes les tâches.

L'exemple ferme toutes les instances d' FileStream dans un bloc d' finally une fois que les tâches soient terminées. Si chaque FileStream était plutôt créé dans une instruction d' using , FileStream peut être rejeté avant que la tâche a été terminée.

Notez que toute push de performances sont presque entièrement du traitement parallèle et pas de traitement asynchrone. Les avantages de asynchrony sont qu'il ne joignez pas plusieurs threads, et qu'elle n'attachement 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
public async void ProcessWriteMult()
{
    string folder = @"tempfolder\";
    List<Task> tasks = new List<Task>();
    List<FileStream> sourceStreams = new List<FileStream>();

    try
    {
        for (int index = 1; index <= 10; index++)
        {
            string text = "In file " + index.ToString() + "\r\n";

            string fileName = "thefile" + index.ToString("00") + ".txt";
            string filePath = folder + fileName;

            byte[] encodedText = Encoding.Unicode.GetBytes(text);

            FileStream sourceStream = new FileStream(filePath,
                FileMode.Append, FileAccess.Write, FileShare.None,
                bufferSize: 4096, useAsync: true);

            Task theTask = sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
            sourceStreams.Add(sourceStream);

            tasks.Add(theTask);
        }

        await Task.WhenAll(tasks);
    }

    finally
    {
        foreach (FileStream sourceStream in sourceStreams)
        {
            sourceStream.Close();
        }
    }
}

En utilisant les méthodes d' WriteAsync et d' ReadAsync , vous pouvez spécifier CancellationToken, que vous pouvez utiliser pour annuler le milieu de en cours de exécution. Pour plus d'informations, consultez Réglage de votre application Async (C# et Visual Basic) et Annulation dans les threads managés.

Voir aussi

Tâches

Procédure pas à pas : utilisation du débogueur avec les méthodes Async

Concepts

Programmation asynchrone avec Async et Await (C# et Visual Basic)

Types de retour Async (C# et Visual Basic)

Flux de contrôle dans les programmes Async (C# et Visual Basic)