Share via


Asynchrone bestands-I/O

Met asynchrone bewerkingen kunt u resource-intensieve I/O-bewerkingen uitvoeren zonder de hoofdthread te blokkeren. Deze prestatieoverweging is met name belangrijk in een Windows 8.x Store-app of -desktop-app, waarbij een tijdrovende streambewerking de UI-thread kan blokkeren en uw app kan weergeven alsof deze niet werkt.

Vanaf .NET Framework 4.5 bevatten de I/O-typen asynchrone methoden om asynchrone bewerkingen te vereenvoudigen. Een asynchrone methode bevat Async de naam, zoals ReadAsync, WriteAsync, CopyToAsync, FlushAsync, en ReadLineAsyncReadToEndAsync. Deze asynchrone methoden worden geïmplementeerd op streamklassen, zoals Stream, FileStreamen , en MemoryStreamop klassen die worden gebruikt voor het lezen van of schrijven naar streams, zoals TextReader en TextWriter.

In .NET Framework 4 en eerdere versies moet u methoden BeginRead zoals asynchrone I/O-bewerkingen implementeren.EndRead Deze methoden zijn nog steeds beschikbaar in de huidige .NET-versies ter ondersteuning van verouderde code; Met de asynchrone methoden kunt u echter eenvoudiger asynchrone I/O-bewerkingen implementeren.

C# en Visual Basic hebben elk twee trefwoorden voor asynchrone programmering:

  • Async (Visual Basic) of async (C#) modifier, die wordt gebruikt om een methode te markeren die een asynchrone bewerking bevat.

  • Await (Visual Basic) of await (C#) operator, die wordt toegepast op het resultaat van een asynchrone methode.

Als u asynchrone I/O-bewerkingen wilt implementeren, gebruikt u deze trefwoorden in combinatie met de asynchrone methoden, zoals wordt weergegeven in de volgende voorbeelden. Zie Asynchrone programmering met asynchroon programmeren en wachten (C#) of Asynchroon programmeren met Async en Await (Visual Basic) voor meer informatie.

In het volgende voorbeeld ziet u hoe u twee FileStream objecten gebruikt om bestanden asynchroon van de ene map naar de andere te kopiëren. U ziet dat de Click gebeurtenis-handler voor het Button besturingselement is gemarkeerd met de async modifier, omdat deze een asynchrone methode aanroept.

using System;
using System.Threading.Tasks;
using System.Windows;
using System.IO;

namespace WpfApplication
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            string startDirectory = @"c:\Users\exampleuser\start";
            string endDirectory = @"c:\Users\exampleuser\end";

            foreach (string filename in Directory.EnumerateFiles(startDirectory))
            {
                using (FileStream sourceStream = File.Open(filename, FileMode.Open))
                {
                    using (FileStream destinationStream = File.Create(Path.Combine(endDirectory, Path.GetFileName(filename))))
                    {
                        await sourceStream.CopyToAsync(destinationStream);
                    }
                }
            }
        }
    }
}
Imports System.IO

Class MainWindow

    Private Async Sub Button_Click(sender As Object, e As RoutedEventArgs)
        Dim StartDirectory As String = "c:\Users\exampleuser\start"
        Dim EndDirectory As String = "c:\Users\exampleuser\end"

        For Each filename As String In Directory.EnumerateFiles(StartDirectory)
            Using SourceStream As FileStream = File.Open(filename, FileMode.Open)
                Using DestinationStream As FileStream = File.Create(EndDirectory + filename.Substring(filename.LastIndexOf("\"c)))
                    Await SourceStream.CopyToAsync(DestinationStream)
                End Using

            End Using
        Next
    End Sub

End Class

Het volgende voorbeeld is vergelijkbaar met de vorige, maar gebruikt StreamReader en StreamWriter objecten om de inhoud van een tekstbestand asynchroon te lezen en te schrijven.

private async void Button_Click(object sender, RoutedEventArgs e)
{
    string UserDirectory = @"c:\Users\exampleuser\";

    using (StreamReader SourceReader = File.OpenText(UserDirectory + "BigFile.txt"))
    {
        using (StreamWriter DestinationWriter = File.CreateText(UserDirectory + "CopiedFile.txt"))
        {
            await CopyFilesAsync(SourceReader, DestinationWriter);
        }
    }
}

public async Task CopyFilesAsync(StreamReader Source, StreamWriter Destination)
{
    char[] buffer = new char[0x1000];
    int numRead;
    while ((numRead = await Source.ReadAsync(buffer, 0, buffer.Length)) != 0)
    {
        await Destination.WriteAsync(buffer, 0, numRead);
    }
}
Private Async Sub Button_Click(sender As Object, e As RoutedEventArgs)
    Dim UserDirectory As String = "c:\Users\exampleuser\"

    Using SourceReader As StreamReader = File.OpenText(UserDirectory + "BigFile.txt")
        Using DestinationWriter As StreamWriter = File.CreateText(UserDirectory + "CopiedFile.txt")
            Await CopyFilesAsync(SourceReader, DestinationWriter)
        End Using
    End Using
End Sub

Public Async Function CopyFilesAsync(Source As StreamReader, Destination As StreamWriter) As Task
    Dim buffer(4095) As Char
    Dim numRead As Integer

    numRead = Await Source.ReadAsync(buffer, 0, buffer.Length)
    Do While numRead <> 0
        Await Destination.WriteAsync(buffer, 0, numRead)
        numRead = Await Source.ReadAsync(buffer, 0, buffer.Length)
    Loop

End Function

In het volgende voorbeeld ziet u het code-behind-bestand en het XAML-bestand dat wordt gebruikt om een bestand als een Stream in een Windows 8.x Store-app te openen en de inhoud ervan te lezen met behulp van een exemplaar van de StreamReader klasse. Het maakt gebruik van asynchrone methoden om het bestand als een stroom te openen en de inhoud ervan te lezen.

using System;
using System.IO;
using System.Text;
using Windows.Storage.Pickers;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace ExampleApplication
{
    public sealed partial class BlankPage : Page
    {
        public BlankPage()
        {
            this.InitializeComponent();
        }

        private async void Button_Click_1(object sender, RoutedEventArgs e)
        {
            StringBuilder contents = new StringBuilder();
            string nextLine;
            int lineCounter = 1;

            var openPicker = new FileOpenPicker();
            openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
            openPicker.FileTypeFilter.Add(".txt");
            StorageFile selectedFile = await openPicker.PickSingleFileAsync();

            using (StreamReader reader = new StreamReader(await selectedFile.OpenStreamForReadAsync()))
            {
                while ((nextLine = await reader.ReadLineAsync()) != null)
                {
                    contents.AppendFormat("{0}. ", lineCounter);
                    contents.Append(nextLine);
                    contents.AppendLine();
                    lineCounter++;
                    if (lineCounter > 3)
                    {
                        contents.AppendLine("Only first 3 lines shown.");
                        break;
                    }
                }
            }
            DisplayContentsBlock.Text = contents.ToString();
        }
    }
}
Imports System.Text
Imports System.IO
Imports Windows.Storage.Pickers
Imports Windows.Storage

NotInheritable Public Class BlankPage
    Inherits Page



    Private Async Sub Button_Click_1(sender As Object, e As RoutedEventArgs)
        Dim contents As StringBuilder = New StringBuilder()
        Dim nextLine As String
        Dim lineCounter As Integer = 1

        Dim openPicker = New FileOpenPicker()
        openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary

        openPicker.FileTypeFilter.Add(".txt")
        Dim selectedFile As StorageFile = Await openPicker.PickSingleFileAsync()

        Using reader As StreamReader = New StreamReader(Await selectedFile.OpenStreamForReadAsync())
            nextLine = Await reader.ReadLineAsync()
            While (nextLine <> Nothing)
                contents.AppendFormat("{0}. ", lineCounter)
                contents.Append(nextLine)
                contents.AppendLine()
                lineCounter = lineCounter + 1
                If (lineCounter > 3) Then
                    contents.AppendLine("Only first 3 lines shown.")
                    Exit While
                End If
                nextLine = Await reader.ReadLineAsync()
            End While
        End Using
        DisplayContentsBlock.Text = contents.ToString()
    End Sub
End Class
<Page
    x:Class="ExampleApplication.BlankPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ExampleApplication"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel Background="{StaticResource ApplicationPageBackgroundBrush}" VerticalAlignment="Center" HorizontalAlignment="Center">
        <TextBlock Text="Display lines from a file."></TextBlock>
        <Button Content="Load File" Click="Button_Click_1"></Button>
        <TextBlock Name="DisplayContentsBlock"></TextBlock>
    </StackPanel>
</Page>

Zie ook