Aracılığıyla paylaş


Dosya Erişimi için Async Kullanma (C# ve Visual Basic)

Kullanabileceğiniz zaman uyumsuz dosyalara erişmek için özellik.Async özelliğini kullanarak, çaðrýlarý kullanarak veya birden fazla yöntem veya lambda ifadeleri kodunuzu bölme zaman uyumsuz yöntemlerini çağırabilir.Zaman uyumlu kod zaman uyumsuz hale getirmek için yalnızca zaman uyumlu bir yöntem yerine zaman uyumsuz yöntemini çağırın ve koda birkaç anahtar sözcük ekleyin.

Asynchrony için dosya erişim çağrıları eklemek için aşağıdaki nedenlerle düşünebilirsiniz:

  • Operasyon başlatan kullanıcı Arabirimi iş parçacığı diğer işleri yerine getirebildiğinden asynchrony UI uygulamaları daha iyi yanıt vermesini sağlar.UI iş parçacığı kod yürütmesi gerekiyor, (örneğin, 50'den fazla milisaniye) çok uzun zaman alıyor, kullanıcı Arabirimi ve UI iş parçacığı, yeniden klavye işlemek ve fare giriş ve diğer olaylar g/Ç işlemi tamamlanana kadar donabilir.

  • Asynchrony, iş parçacığı ihtiyacını azaltarak ASP ölçeklenebilirliğini ve diğer sunucu tabanlı uygulamalar geliştirir.Uygulama yanıt başına adanmış bir iş parçacığını kullanır ve bedel istekleri aynı anda işlenmekte, bedel iş parçacığı gereklidir.Zaman uyumsuz işlemler genellikle bir iş parçacığı bekleme sırasında kullanmanız gerekmez.Varolan g/Ç tamamlanma iş parçacığı kısa bir süre sonunda kullanırlar.

  • Dosya erişim işlemi gecikmesi geçerli koşullar altında çok düşük olabilir, ancak gecikme gelecekte önemli ölçüde artırabilir.Örneğin, bir dosyayı dünya genelinde bir sunucuya taşınmış olabilir.

  • Eklenen Async özelliğini kullanarak ek yük küçük.

  • Zaman uyumsuz görevler kolayca paralel olarak çalıştırabilirsiniz.

Örnekleri çalıştırma

[!NOT]

Bu konudaki örnekleri için uygulama Windows Mağazası olan uygulamalar Windows 8 , tam ekran ve için uyarlanmış apps touch etkileşim.Zaman uyumsuz dosya Access'te kullanma hakkında bilgi için Windows Mağazası apps, bkz: .NET for Windows Store apps overview ve Dosya ve akış g/Ç.Dosya g/Ç için örnekleri için Windows Mağazası apps karşıdan yükleyebilirsiniz Dosyasına erişimi örnek.

Bu konudaki örneklerde çalıştırmak için oluşturabileceğiniz bir wpf uygulama ya da bir Windows Forms uygulamasý ve ardından add bir düğmesini.Button öğesinin, Click olay, her örnekte ilk yöntemine bir çağrı ekleyin.

Aşağıdaki örneklerde, aşağıdakiler dahil Imports (Visual Basic) ya da using (C#) deyimleri.

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;

FileStream sınıfının kullanımı

Bu konuda kullanım örnekleri FileStream sınıfı, işletim sistemi düzeyinde gerçekleşmesi zaman uyumsuz g/Ç neden olan bir seçenek vardır.Bu seçeneği kullanarak, çoğu durumda bir iş parçacığı havuzu iş parçacığı engellemesini önleyebilirsiniz.Bu seçeneği etkinleştirmek için belirttiğiniz useAsync=true veya options=FileOptions.Asynchronous oluşturucu çağrısı bağımsız değişkeni.

Bu seçenekle kullanamazsınız StreamReader ve StreamWriter doğrudan bir dosya yolu belirterek açarsanız.Ancak, bunları sağlarsanız bu seçeneği kullanabilirsiniz bir Stream , FileStream sınıf açıldı.Bir iş parçacığı havuzu iş parçacığı bloke edilirse, UI iş parçacığı bekleme sırasında kilitli değilse çünkü zaman uyumsuz çağrı UI apps daha hızlı olduğuna dikkat edin.

Metin yazma

Aşağıdaki örnek metin bir dosyaya yazar.Her biri deyimi beklemek, yöntemi hemen çıkar.Dosya g/Ç işlemi tamamlandığında yöntemi await deyiminin ardından gelir ifadesine devam ettirir.Zaman uyumsuz değiştirici await deyimini yöntemleri tanımında olduğuna dikkat edin.

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);
    };
}

Özgün örnek ifadesi olan await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);, contraction, aşağıdaki iki ifade edilir:

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

İlk ifade bir görev verir ve başlatmak dosya işleme neden olur.İkinci ifade await ile hemen çıkın ve başka bir göreve dönmek yöntem neden olur.Daha sonra işleme dosyası tamamlandığında, yürütme await aşağıdaki deyimi döndürür.Daha fazla bilgi için, bkz. Denetim akışında zaman uyumsuz programlar (C# ve Visual Basic) ve İzlenecek Yol: Hata Ayıklayıcıyı Zaman Uyumsuz Yöntemlerle Kullanma.

Metin okuma

Aşağıdaki örnek bir dosyadan okur.Metin arabelleğe alınmış olup, bu durumda, içine yerleştirilen bir StringBuilder.Aksine önceki örnekte await değerlendirmenin bir değer üretir.ReadAsync Yöntemi döndürür bir Task<Int32>, await değerlendirmenin oluşturur böylece bir Int32 değeri (numRead) işlem tamamlandıktan sonra.Daha fazla bilgi için bkz. Zaman uyumsuz dönüş türleri (C# ve 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();
    }
}

Paralel zaman uyumsuz g/Ç

Aşağıdaki örnekte, 10 metin dosyaları yazarak paralel işlemeyi gösterilmiştir.Her dosya için WriteAsync yöntemi sonra görevler listesine eklenen görev verir.await Task.WhenAll(tasks); Deyimi yöntem çıkar ve içindeki dosya işleme yöntemi geri döndüğünde tüm görevleri tamamlamak.

Tüm örnek kapatır FileStream de örnekler bir finally görevleri tamamlandıktan sonra engelleyin.Her, FileStream , bunun yerine oluşturulduğu bir using deyimi, FileStream görev tamamlanmadan önce elden.

Herhangi bir performans artışı neredeyse tamamen paralel işleme ve zaman uyumsuz işlem olduğunu unutmayın.Asynchrony avantajları tedariği birbirine, çoklu iş parçacıklarını bağlamanın etmez olduğunu ve tedariği birbirine, kullanıcı arabirimi iş parçacığını bağlamanın değil,'dır.

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();
        }
    }
}

Kullanırken, WriteAsync ve ReadAsync yöntemleri, belirtebileceğiniz bir CancellationToken, hangi işlemi mid-stream iptal etmek için kullanabilirsiniz.Daha fazla bilgi için, bkz. Async Uygulamanızda Hassas Ayar Yapma (C# ve Visual Basic) ve Yönetilen iş parçacıkları olarak iptali.

Ayrıca bkz.

Görevler

İzlenecek Yol: Hata Ayıklayıcıyı Zaman Uyumsuz Yöntemlerle Kullanma

Kavramlar

Zaman uyumsuz zaman uyumsuz programlama ve beklemek (C# ve Visual Basic)

Zaman uyumsuz dönüş türleri (C# ve Visual Basic)

Denetim akışında zaman uyumsuz programlar (C# ve Visual Basic)