Dosya Erişimi için Asenkron Kullanma (Visual Basic)

Dosyalara erişmek için Asenkron özelliğini kullanın. Zaman Uyumsuz özelliğini kullanarak, geri çağırmaları kullanmadan veya kodunuzu birden çok yönteme veya lambda ifadesine bölmeden zaman uyumsuz yöntemlere çağrı yapabilirsiniz. Zaman uyumlu kodu zaman uyumsuz yapmak için, zaman uyumlu bir yöntem yerine zaman uyumsuz bir yöntem çağırın ve koda birkaç anahtar sözcük ekleyin.

Şu nedenlerle dosya erişim çağrılarına zaman uyumsuz eklemeyi göz önünde bulundurun:

  • Zaman uyumsuzluk, işlemi başlatan kullanıcı arabirimi iş parçacığı başka işler gerçekleştirebildiğinden, kullanıcı arayüzü uygulamalarını daha duyarlı hale getirir. UI iş parçacığının uzun süren bir kodu çalıştırması gerekiyorsa (örneğin, 50 milisaniyeden fazla), G/Ç işlemi tamamlanana kadar kullanıcı arabirimi donabilir ve UI iş parçacığı klavye ve fare girdilerini ve diğer olayları yeniden işleyebilir.

  • Zaman uyumsuzluğu, iş parçacığı gereksinimini azaltarak ASP.NET ve diğer sunucu tabanlı uygulamaların ölçeklenebilirliğini artırır. Uygulama yanıt başına ayrılmış bir iş parçacığı kullanıyorsa ve bin istek aynı anda işleniyorsa, bin iş parçacığı gerekir. Eşzamanlı olmayan işlemler genellikle bekleme sırasında bir thread kullanmak zorunda değildir. Mevcut G/Ç tamamlama iş parçacığını işlemin sonunda kısa bir süreliğine kullanırlar.

  • Geçerli koşullarda dosya erişim işleminin gecikme süresi çok düşük olabilir, ancak gecikme süresi gelecekte büyük ölçüde artabilir. Örneğin, bir dosya dünyanın her yanındaki bir sunucuya taşınabilir.

  • Asenkron özelliğini kullanmanın ek yükü küçüktür.

  • Çağıran iş parçacığını engellemeden birden çok zaman uyumsuz G/Ç işlemi çalıştırılabilir.

Örnekleri çalıştırma

Bu konudaki örnekleri çalıştırmak için bir WPF Uygulaması veya Windows Forms Uygulaması oluşturun ve ardından bir Düğme ekleyin. Düğmenin Click olayında, her örnekteki ilk yönteme bir çağrı ekleyin.

Aşağıdaki örneklerde aşağıdaki Imports deyimleri ekleyin.

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

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

Bu konudaki örneklerde, işletim sistemi düzeyinde zaman uyumsuz G/Ç oluşmasına neden olan bir seçeneği bulunan FileStream sınıfı kullanılır. Bu seçeneği kullanarak birçok durumda ThreadPool iş parçacığını engellemekten kaçınabilirsiniz. Bu seçeneği etkinleştirmek için oluşturucu çağrısında useAsync=true veya options=FileOptions.Asynchronous bağımsız değişkenini belirtin.

Bu seçeneği, bir dosya yolu belirterek StreamReader ve StreamWriter doğrudan açarsanız kullanamazsınız. Ancak, bir Stream sağlar ve FileStream sınıfının açmasına izin verirseniz bu seçeneği kullanabilirsiniz. UI iş parçacığı bekleme sırasında engellenmediğinden, ThreadPool iş parçacığı engellenmiş olsa bile kullanıcı arabirimi uygulamalarında zaman uyumsuz çağrılar daha hızlıdır.

Metin yazma

Aşağıdaki örnek bir dosyaya metin yazar. Her bir 'await' ifadesinde, metot anında durur ve çıkar. G/Ç dosyası işlemleri tamamlandığında, yöntem await deyimini izleyen deyimde devam eder. Yöntemlerin tanımında await deyimini kullanan async belirteci bulunur.

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

Özgün örnekte, aşağıdaki iki ifadenin Await sourceStream.WriteAsync(encodedText, 0, encodedText.Length) ile kısaltılmış şekli olan ifade bulunur.

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

İlk ifade bir görevi döndürür ve dosya işlemenin başlamasına neden olur. await ile ikinci ifade, yöntemin hemen sona erip farklı bir görev döndürmesine neden olur. Dosya işleme işlemi daha sonra tamamlandığında yürütme, await öğesini izleyen deyimine döner. Daha fazla bilgi için bkz. Zaman Uyumsuz Programlarda Denetim Akışı (Visual Basic).

Metni okuma

Aşağıdaki örnek bir dosyadan metin okur. Metin arabelleğe alınır ve bu durumda StringBuilder içine yerleştirilir. Önceki örnekten farklı olarak, await ifadesinin değerlendirilmesi bir değer üretir. ReadAsync yöntemi bir Task<Int32> döndürür, bu nedenle await değerlendirmesi işlem tamamlandıktan sonra bir Int32 değer (numRead) üretir. Daha fazla bilgi için bkz Zaman Uyumsuz Dönüş Türleri (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

Birden çok zaman uyumsuz G/Ç işlemi

Aşağıdaki örnek birden çok zaman uyumsuz yazma çalışması başlatır. Runtime bu işlemleri kuyruğa alır ve altyapı uygulaması, platforma ve yapılandırmaya bağlı olarak işletim sistemi (OS) zaman uyumsuz G/Ç veya iş parçacığı havuzu iş parçacıklarını kullanabilir, bu nedenle gerçek eşzamanlılık işletim sistemine ve donanıma bağlıdır. Her dosya için WriteAsync yöntemi, görev listesine eklenen bir görevi döndürür. Await Task.WhenAll(tasks) ifade, yöntemden çıkar ve tüm görevler için dosya işlemi tamamlandığında yöntem içinde yeniden başlar.

Örnek, görevler tamamlandıktan sonra bir FileStream bloktaki tüm Finally örnekleri kapatır. Eğer her FileStream, bir Using ifadesinde oluşturulmuş olsaydı, FileStream, görev tamamlanmadan önce atılabilirdi.

Zaman uyumsuz yaklaşım, G/Ç beklemedeyken çağıran iş parçacığını engellemeyi önler. Çoğu durumda aktarım hızı geliştirmeleri işletim sistemine, donanıma ve bazı platformlarda iş parçacığı havuzu sınırları ve zamanlama gibi .NET çalışma zamanı davranışına bağlı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

WriteAsync ve ReadAsync yöntemlerini kullanırken, işlemi akışın ortasında iptal etmek için bir CancellationToken belirtebilirsiniz. Daha fazla bilgi için bkz. Fine-Tuning Zaman Uyumsuz Uygulamanız (Visual Basic) ve Yönetilen İş Parçacıklarında İptal.

Ayrıca bakınız