Aracılığıyla paylaş


Asenkron Dosya G/Ç

Zaman uyumsuz işlemler, ana iş parçacığını engellemeden yoğun kaynak kullanımlı G/Ç işlemleri gerçekleştirmenizi sağlar. Zaman alan bir akış işleminin ui iş parçacığını engelleyebildiği ve uygulamanızın çalışmıyor gibi görünmesini sağlayabildiği bir Windows 8.x Store uygulamasında veya masaüstü uygulamasında bu performansla ilgili dikkat edilmesi gerekenler özellikle önemlidir.

.NET Framework 4.5'ten itibaren, Giriş/Çıkış türleri asenkron işlemleri basitleştirmek için asenkron yöntemler içerir. Zaman uyumsuz bir yöntemin adı Async içerir ve bu ad ReadAsync, WriteAsync, CopyToAsync, FlushAsync, ReadLineAsync ve ReadToEndAsync gibi olabilir. Bu zaman uyumsuz yöntemler, Stream, FileStream ve MemoryStream gibi akış sınıflarında ve TextReader ile TextWriter gibi akışlardan okumak ya da akışlara yazmak için kullanılan sınıflarda uygulanır.

.NET Framework 4 ve önceki sürümlerinde, zaman uyumsuz G/Ç işlemlerini gerçekleştirmek için BeginRead ve EndRead gibi yöntemler kullanmanız gerekir. Bu yöntemler, eski kodu desteklemek için mevcut .NET sürümlerinde halen kullanılabilir; ancak yöntemler, zaman uyumsuz G/Ç operasyonlarını daha kolay uygulamanıza yardımcı olur.

C# ve Visual Basic'in her birinin zaman uyumsuz programlama için iki anahtar sözcüğü vardır:

  • Async (Visual Basic) veya async (C#) değiştirici, zaman uyumsuz işlem içeren bir yöntemi işaretlemek için kullanılır.

  • Await (Visual Basic) veya await (C#) işleci, zaman uyumsuz bir yöntemin sonucuna uygulanır.

Zaman uyumsuz G/Ç işlemlerini uygulamak için aşağıdaki örneklerde gösterildiği gibi bu anahtar sözcükleri zaman uyumsuz yöntemlerle birlikte kullanın. Daha fazla bilgi için bkz. Async ve Await (C#) ile Zaman Uyumsuz Programlama veya Async ve Await (Visual Basic) ile Zaman Uyumsuz Programlama.

Aşağıdaki örnekte, dosyaları bir dizinden diğerine zaman uyumsuz olarak kopyalamak için iki FileStream nesnenin nasıl kullanılacağı gösterilmektedir. Click denetiminin Button olay işleyicisinin, zaman uyumsuz bir yöntemi çağırdığı için async değiştiriciyle işaretlendiğini fark edin.

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

Sonraki örnek öncekine benzer, ancak bir metin dosyasının içeriğini zaman uyumsuz olarak okumak ve yazmak için StreamReader ve StreamWriter nesnelerini kullanır.

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

Sonraki örnekte, bir dosyayı Windows 8.x Store uygulamasında Stream olarak açmak ve StreamReader sınıfının bir örneğini kullanarak içeriğini okumak için kullanılan arka planda kod dosyası ve XAML dosyası gösterilmektedir. Dosyayı akış olarak açmak ve içeriğini okumak için zaman uyumsuz yöntemler kullanır.

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>

Ayrıca bakınız