Share via


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

Dosyalara erişmek için Zaman Uyumsuz özelliğini kullanabilirsiniz. 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ır ve koda birkaç anahtar sözcük eklersiniz.

Dosya erişim çağrılarına zaman uyumsuz eklemenin aşağıdaki nedenlerini göz önünde bulundurabilirsiniz:

  • İşlemi başlatan kullanıcı arabirimi iş parçacığı başka işler gerçekleştirebildiğinden, zaman uyumsuz olması ui uygulamalarını daha duyarlı hale getirir. Ui iş parçacığının uzun süren bir kod yürütmesi gerekiyorsa (örneğin, 50 milisaniyeden fazla), kullanıcı arabirimi G/Ç tamamlanana kadar donabilir ve kullanıcı arabirimi iş parçacığı klavye ve fare girişini 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. Zaman uyumsuz işlemlerin genellikle bekleme sırasında iş parçacığı kullanması gerekmez. Var olan G/Ç tamamlama iş parçacığını kısa bir süre sonunda kullanırlar.

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

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

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

Örnekleri Çalıştırma

Bu konudaki örnekleri çalıştırmak için bir WPF Uygulaması veya Windows Forms Uygulaması oluşturabilir ve ardından bir Düğme ekleyebilirsiniz. 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 olan sınıfı kullanılır FileStream . 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 belirtirsiniz.

Bu seçeneği ile ve StreamWriter dosya StreamReader yolu belirterek doğrudan açarsanız kullanamazsınız. Ancak, sınıfın açtığı bir StreamFileStream sağlarsanız bu seçeneği kullanabilirsiniz. Bekleme sırasında kullanıcı arabirimi iş parçacığı engellenmediğinden ThreadPool iş parçacığı engellenmiş olsa bile kullanıcı arabirimi uygulamalarında zaman uyumsuz çağrıların daha hızlı olduğunu unutmayın.

Metin Yazma

Aşağıdaki örnek bir dosyaya metin yazar. Her await deyiminde yöntemi hemen çıkar. G/Ç dosyası tamamlandığında yöntemi await deyimini izleyen deyimde devam eder. Zaman uyumsuz değiştiricinin await deyimini kullanan yöntemlerin tanımında olduğunu unutmayın.

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 deyimin Await sourceStream.WriteAsync(encodedText, 0, encodedText.Length)daralması olan deyimi bulunur:

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

İlk deyim bir görev döndürür ve dosya işlemenin başlamasına neden olur. await ile ikinci deyimi, yönteminin hemen çıkıp 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).

Metin Okuma

Aşağıdaki örnek bir dosyadan metin okur. Metin arabelleğe alınır ve bu durumda içine StringBuilderyerleştirilir. Önceki örnekten farklı olarak await değerinin değerlendirilmesi bir değer üretir. ReadAsync yöntemi birInt32<>Task 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  

Paralel Zaman Uyumsuz G/Ç

Aşağıdaki örnek, 10 metin dosyası yazarak paralel işlemeyi gösterir. Her dosya için WriteAsync yöntemi, daha sonra bir görev listesine eklenen bir görev döndürür. deyimi Await Task.WhenAll(tasks) yönteminden çıkar ve tüm görevler için dosya işleme tamamlandığında yöntemi içinde devam eder.

Örnek, görevler tamamlandıktan sonra bir Finally bloktaki tüm FileStream örnekleri kapatır. Her FileStream biri bir Imports deyimde oluşturulduysa, FileStream görev tamamlanmadan önce atılabilir.

Herhangi bir performans artışının zaman uyumsuz işlemeden değil neredeyse tamamen paralel işlemeden kaynaklandığını unutmayın. Zaman uyumsuzliğin avantajları, birden çok iş parçacığını bağlamaması ve kullanıcı arabirimi iş parçacığını bağlamaması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  

ve ReadAsync yöntemlerini kullanırken, akışın WriteAsync ortasında işlemi iptal etmek için kullanabileceğiniz bir CancellationTokenbelirtebilirsiniz. Daha fazla bilgi için bkz. Yönetilen İş Parçacıklarında Zaman Uyumsuz Uygulamanızda İnce Ayarlama (Visual Basic) ve İptal.

Ayrıca bkz.