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.