Async ve Await (Visual Basic) ile zaman uyumsuz programlama
Zaman uyumsuz programlama kullanarak performans sorunlarını önleyebilir ve uygulamanızın genel yanıt verme becerisini geliştirebilirsiniz. Ancak, zaman uyumsuz uygulamalar yazmaya yönelik geleneksel teknikler karmaşık olabilir ve bu nedenle yazılmaları, hataların ayıklanması ve bakım yapılması zorlaşabilir.
Visual Studio 2012, .NET Framework 4.5 ve üzeri sürümlerde ve Windows Çalışma Zamanı zaman uyumsuz desteği kullanan basitleştirilmiş bir yaklaşım olan zaman uyumsuz programlamayı kullanıma sunulmuştur. Derleyici, normalde geliştiricinin yaptığı zor işi yapar ve uygulamanız zaman uyumlu koda benzer bir mantıksal yapıyı korur. Sonuç olarak, zaman uyumsuz programlama avantajlarının tamamını çok daha az çaba harcayarak elde edebilirsiniz.
Bu konu zaman uyumsuz programlamanın ne zaman ve nasıl kullanılması gerektiği hakkında genel bakış içerir ve ayrıntılar ve örnekler içeren destek konularına bağlantılar sunar.
Zaman uyumsuzluk yanıt hızını artırır
Zaman uyumsuzluk, uygulamanızın Web'e erişmesi gibi engelleme olasılığı bulunan faaliyetler için önemlidir. Web kaynağına erişim bazen yavaş veya gecikmeli olabilir. Böyle bir etkinlik zaman uyumlu işlemde engellenirse uygulamanın tamamı beklemelidir. Uygulama, zaman uyumsuz bir işlemde olası engelleme görevi sona erinceye kadar web kaynağına bağlı olmayan diğer işlerle devam eder.
Aşağıdaki tabloda, zaman uyumsuz programlamanın yanıt verme hızını geliştirdiği genel alanlar gösterilmektedir. .NET Framework 4.5 ve Windows Çalışma Zamanı listelenen API'ler zaman uyumsuz programlamayı destekleyen yöntemler içerir.
Uygulama alanı | Zaman uyumsuz yöntemler içeren API'leri destekleme |
---|---|
Web erişimi | HttpClient, SyndicationClient |
Dosyalarla çalışma | StorageFile, StreamWriter, StreamReader, XmlReader |
Görüntülerle çalışma | MediaCapture, BitmapEncoder, BitmapDecoder |
WCF programlama | Zaman Uyumlu ve Zaman Uyumsuz İşlemler |
Tüm kullanıcı arabirimi ilişkili faaliyetler genellikle tek bir iş parçacığını paylaştığından, zaman uyumsuzluğun kullanıcı arabirimi iş parçacığına erişen uygulamalar için özellikle önem taşıdığı kanıtlanmıştır. Herhangi bir işlem zaman uyumlu bir uygulamada engellenirse, tümü engellenir. Uygulamanız yanıt vermiyordur ve bunu uygulamanın beklediği değil de başarısız olduğu şeklinde yorumlayabilirsiniz.
Zaman uyumsuz yöntemleri kullandığınızda, uygulama arabirime yanıt vermeye devam eder. Bir pencereyi yeniden boyutlandırabilir veya simge durumuna küçültebilir ya da bitmesini beklemek istemiyorsanız kapatabilirsiniz.
Zaman uyumsuz tabanlı yaklaşım otomatik bir iletimin eşdeğerini, zaman uyumsuz işlemler tasarlarken seçebileceğiniz seçenekler listesine ekler. Diğer bir deyişle, geleneksel zaman uyumsuz programlamanın tüm avantajlarından yararlanabilirsiniz, buna rağmen geliştiricinin daha az çaba sarf etmesi gerekir.
Zaman uyumsuz yöntemleri yazmak daha kolaydır
Visual Basic içindeki Async ve Await anahtar sözcükleri, zaman uyumsuz programlamanın kalbidir. Bu iki anahtar sözcüğü kullanarak .NET Framework veya Windows Çalışma Zamanı kaynakları kullanarak zaman uyumlu bir yöntem oluşturmak kadar kolay bir zaman uyumsuz yöntem oluşturabilirsiniz. kullanarak Async
tanımladığınız zaman uyumsuz yöntemlere zaman Await
uyumsuz yöntemler denir.
Aşağıdaki örnekte zaman uyumsuz bir yöntem gösterilmektedir. Kodda yer alan hemen hemen her şey size tamamen tanıdık gelmiş olmalıdır. Açıklamalar, zaman uyumsuzluğu eklemek için oluşturduğunuz özellikleri çağırır.
Bu konunun sonunda tam bir Windows Presentation Foundation (WPF) örnek dosyası bulabilir ve örneği Zaman Uyumsuz Örnek: "Async ve Await ile Zaman Uyumsuz Programlama" bölümünden indirebilirsiniz.
' Three things to note about writing an Async Function:
' - The function has an Async modifier.
' - Its return type is Task or Task(Of T). (See "Return Types" section.)
' - As a matter of convention, its name ends in "Async".
Async Function AccessTheWebAsync() As Task(Of Integer)
Using client As New HttpClient()
' Call and await separately.
' - AccessTheWebAsync can do other things while GetStringAsync is also running.
' - getStringTask stores the task we get from the call to GetStringAsync.
' - Task(Of String) means it is a task which returns a String when it is done.
Dim getStringTask As Task(Of String) =
client.GetStringAsync("https://docs.microsoft.com/dotnet")
' You can do other work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork()
' The Await operator suspends AccessTheWebAsync.
' - AccessTheWebAsync does not continue until getStringTask is complete.
' - Meanwhile, control returns to the caller of AccessTheWebAsync.
' - Control resumes here when getStringTask is complete.
' - The Await operator then retrieves the String result from getStringTask.
Dim urlContents As String = Await getStringTask
' The Return statement specifies an Integer result.
' A method which awaits AccessTheWebAsync receives the Length value.
Return urlContents.Length
End Using
End Function
Çağırma GetStringAsync
ile tamamlanmasını bekleme arasında gerçekleştirebileceği bir çalışma yoksaAccessTheWebAsync
, aşağıdaki tek deyimde çağırarak ve bekleyerek kodunuzu basitleştirebilirsiniz.
Dim urlContents As String = Await client.GetStringAsync()
Aşağıdaki özellikler, önceki örneği zaman uyumsuz bir yöntem yapan özellikleri özetler:
Yöntem imzası bir
Async
değiştirici içerir.Zaman uyumsuz yöntemin adı kurala göre "Async" soneki ile sona erer.
Dönüş türü aşağıdaki türlerden biridir:
- Yönteminizde işlenenin TResult türüne sahip olduğu bir dönüş deyimi varsa Task(Of TResult).
- Task yönteminizin return deyimi yoksa veya işleneni olmayan bir return deyimi varsa.
- Zaman uyumsuz olay işleyicisi yazıyorsanız sub.
Daha fazla bilgi için bu konunun ilerleyen kısımlarındaki "Dönüş Türleri ve Parametreler" bölümüne bakın.
Yöntem, genellikle beklenen zaman uyumsuz işlem tamamlanana kadar devam edemediği bir noktayı işaretleyen en az bir await ifadesi içerir. Bu sırada yöntem askıya alınır ve denetim yöntemi arayana döner. Bu konunun sonraki bölümünde askıya alma noktasında neler olduğu gösterilmektedir.
Zaman uyumsuz yöntemlerde ne yapmak istediğinizi belirtmek için sağlanan anahtar sözcükleri ve türleri kullanırsınız ve denetim, askıya alınan bir yöntemde await noktasına geldiğinde olması gerekenlerin izlenmesi dahil olmak üzere geri kalan işlemleri derleyici yapar. Döngüler ve özel durum işleme gibi bazı rutin işlemlerin geleneksel zaman uyumsuz kodla yapılması zor olabilir. Zaman uyumsuz bir yöntemde, bu öğeleri olabildiğince zaman uyumlu çözümde yazarsınız ve sorun çözülür.
.NET Framework önceki sürümlerindeki zaman uyumsuzlar hakkında daha fazla bilgi için bkz. TPL ve Geleneksel .NET Framework Zaman Uyumsuz Programlama.
Async yönteminde ne olur?
Zaman uyumsuz programlama ile ilgili olarak anlamanız gereken en önemli şey, denetim akışının yöntemden yönteme nasıl geçtiğidir. Aşağıdaki diyagram işlemde size yol açar:
Diyagramdaki sayılar aşağıdaki adımlara karşılık gelir:
Olay işleyicisi zaman uyumsuz yöntemi çağırır ve bekler
AccessTheWebAsync
.AccessTheWebAsync
bir HttpClient örnek oluşturur ve bir web sitesinin içeriğini dize olarak indirmek için zaman uyumsuz yöntemini çağırır GetStringAsync .İlerleme durumunu askıya alan bir şey olur
GetStringAsync
. Bir web sitesinin indirmesini veya başka bir engelleyen etkinliği beklemesi gerekebilir. Engelleyici kaynakları önlemek için,GetStringAsync
denetimi çağıranı olanAccessTheWebAsync
öğesine verir.GetStringAsync
, TResult'un bir dize olduğu bir Task(Of TResult) döndürür veAccessTheWebAsync
görevi değişkenegetStringTask
atar. Görev, çalışmaGetStringAsync
tamamlandığında gerçek bir dize değeri üretme taahhüdüyle çağrısı için devam eden işlemi temsil eder.getStringTask
Henüz beklenmadığı için,AccessTheWebAsync
sonucuna bağlıGetStringAsync
olmayan diğer çalışmalarla devam edebilir. Bu iş, zaman uyumlu yöntemineDoIndependentWork
yapılan bir çağrı ile temsil edilir.DoIndependentWork
, işini yapıp çağırana geri dönen zaman uyumlu bir yöntemdir.AccessTheWebAsync
, sonucundan bir sonuçgetStringTask
almadan gerçekleştirebileceği iş dışıdır.AccessTheWebAsync
next, indirilen dizenin uzunluğunu hesaplamak ve döndürmek ister, ancak yöntem dizeye sahip olana kadar bu değeri hesaplayamaz.Bu nedenle,
AccessTheWebAsync
ilerleme durumunu askıya almak ve adlıAccessTheWebAsync
yönteme denetim vermek için bir await işleci kullanır.AccessTheWebAsync
çağırana birTask(Of Integer)
döndürür. Görev, indirilen dizenin uzunluğu olan bir tamsayı sonucu verecek bir taahhüdü temsil eder.Not
Beklemeden önce
AccessTheWebAsync
(ve bu nedenlegetStringTask
) tamamlanmışsaGetStringAsync
, denetim içindeAccessTheWebAsync
kalır. Çağrılan zaman uyumsuz işlem (getStringTask
) zaten tamamlandıysa ve AccessTheWebSync'in nihai sonucu beklemesi gerekmiyorsa askıya alma ve sonra geri dönmeAccessTheWebAsync
gideri boşa gider.Arayanın içinde (bu örnekte olay işleyicisi), işleme düzeni devam eder. Çağıran, sonucu beklemeden
AccessTheWebAsync
önce sonucuna bağlı olmayan başka işler de yapabilir veya çağıran hemen bekler. Olay işleyicisi bekliyorAccessTheWebAsync
veAccessTheWebAsync
bekliyorGetStringAsync
.GetStringAsync
tamamlar ve bir dize sonucu üretir. Dize sonucu, çağrısıGetStringAsync
tarafından beklediğiniz şekilde döndürülmüyor. (Yöntemin 3. adımda zaten bir görev döndürdüğünü unutmayın.) Bunun yerine, dize sonucu yönteminingetStringTask
tamamlanmasını temsil eden görevde depolanır. await işleci sonucu 'dengetStringTask
alır. Atama deyimi, alınan sonucu öğesineurlContents
atar.Dize sonucuna sahip olduğunda
AccessTheWebAsync
, yöntemi dizenin uzunluğunu hesaplayabilir. Ardından, öğesininAccessTheWebAsync
çalışması da tamamlanır ve bekleyen olay işleyicisi devam edebilir. Konunun sonundaki tam örnekte olay işleyicisinin uzunluk sonucundaki değeri aldığını ve yazdığını onaylayabilirsiniz.
Zaman uyumsuz programlama konusunda yeniyseniz, zaman uyumlu ve zaman uyumsuz davranış arasındaki farkları değerlendirmek için bir dakikanızı ayırın. Zaman uyumlu yöntem, işi tamamlandığında döndürür (5. adım), ancak zaman uyumsuz bir yöntem işi askıya alındığında görev değeri döndürür (3 ve 6. adım). Zaman uyumsuz yöntem çalışmasını tamamladığında görev tamamlandı olarak işaretlenir ve varsa sonuç görevde depolanır.
Denetim akışı hakkında daha fazla bilgi için bkz. Zaman Uyumsuz Programlar'da (Visual Basic) Denetim Flow.
API Zaman Uyumsuz Yöntemleri
Zaman uyumsuz programlamayı destekleyen gibi GetStringAsync
yöntemleri nerede bulabileceğinizi merak ediyor olabilirsiniz. .NET Framework 4.5 veya üzeri, ve Await
ile Async
çalışan birçok üye içerir. Bu üyeleri üye adına eklenen "Async" soneki ve veya Task(Of TResult) dönüş türüyle Task tanıyabilirsiniz. Örneğin, System.IO.Stream
sınıfı , ReadAsyncve WriteAsync gibi CopyToAsyncyöntemlerin yanı sıra , Readve Writezaman uyumlu yöntemleri CopyToiçerir.
Windows Çalışma Zamanı, Windows uygulamalarında ve Await
ile Async
kullanabileceğiniz birçok yöntem de içerir. Daha fazla bilgi ve örnek yöntemler için bkz. C# veya Visual Basic zaman uyumsuz API'leri çağırma, Zaman uyumsuz programlama (Windows Çalışma Zamanı uygulamalar) ve WhenAny: .NET Framework ile Windows Çalışma Zamanı arasında köprü oluşturma.
İş Parçacıkları
Zaman uyumsuz yöntemlerin engelleyici olmayan işlemler olmaları amaçlanmıştır. Await
Zaman uyumsuz yöntemdeki bir ifade, beklenen görev çalışırken geçerli iş parçacığını engellemez. Bunun yerine ifade, yöntemin geri kalanını yöntemin devamı olarak imzalar ve denetimi zaman uyumsuz yöntemi arayan kişiye verir.
Async
ve Await
anahtar sözcükleri ek iş parçacıklarının oluşturulmasına neden olmaz. Zaman uyumsuz bir yöntem kendi iş parçacığında çalışmadığından zaman uyumsuz yöntemler çok iş parçacıklı işlem gerektirmez. Yöntem geçerli eşitleme kapsamının üzerinde çalışır ve yalnızca yöntem etkin olduğunda iş parçacığındaki zamanı kullanır. CPU'ya bağlı çalışmayı arka plan iş parçacığına taşımak için kullanabilirsiniz Task.Run , ancak arka plan iş parçacığı yalnızca sonuçların kullanılabilir olmasını bekleyen bir işlemde işe yaramaz.
Zaman uyumsuz programlamaya zaman uyumsuz yaklaşım, hemen hemen her durumda varolan yaklaşımlara tercih edilir. Kod daha basit olduğundan ve yarış koşullarına karşı korumanız gerekmeyen bu yaklaşım özellikle G/Ç'ye bağlı işlemlerden daha BackgroundWorker iyidir. ile birlikte Task.Run, zaman uyumsuz programlama CPU'ya bağlı işlemlerden daha BackgroundWorker iyidir çünkü zaman uyumsuz programlama kodunuzu çalıştırmanın koordinasyon ayrıntılarını iş parçacığı havuzuna aktaran Task.Run
çalışmadan ayırır.
Async ve Await
Zaman Uyumsuz değiştirici kullanarak bir yöntemin zaman uyumsuz bir yöntem olduğunu belirtirseniz, aşağıdaki iki özelliği etkinleştirirsiniz.
İşaretli zaman uyumsuz yöntem, askıya alma noktalarının atanması için Await kullanabilir. await işleci derleyiciye, beklenen zaman uyumsuz işlem tamamlanmadan zaman uyumsuz yöntemin bu noktanın ilerisine devam edemeyeceğini bildirir. Bu sırada denetim, zaman uyumsuz yönteminin arayanına döner.
Bir ifadede
Await
zaman uyumsuz yöntemin askıya alınması yöntemden çıkış oluşturmaz veFinally
bloklar çalışmaz.İşaretli zaman uyumsuz yöntem, kendisinin çağırdığı yöntemler tarafından bekleniyor olabilir.
Zaman uyumsuz yöntem genellikle bir işlecin bir Await
veya daha fazla örneğini içerir, ancak ifadelerin Await
olmaması derleyici hatasına neden olmaz. Zaman uyumsuz bir yöntem bir askıya alma noktasını işaretlemek için işleç Await
kullanmıyorsa, değiştiriciye rağmen Async
zaman uyumlu bir yöntem olarak yürütülür. Derleyici bu tür yöntemler için bir uyarı verir.
Async
ve Await
bağlamsal anahtar sözcüklerdir. Daha fazla bilgi ve örnek için aşağıdaki konulara bakın:
Dönüş türleri ve parametreleri
.NET Framework programlamada zaman uyumsuz bir yöntem genellikle bir Task veya (Of TResult) döndürür. Zaman uyumsuz bir yöntemin içinde, başka bir Await
zaman uyumsuz yönteme yapılan çağrıdan döndürülen bir göreve bir işleç uygulanır.
Yöntem türünde bir işlenen TResult
belirten bir Return deyimi içeriyorsa dönüş türü olarak Task(Of TResult) belirtirsiniz.
Yöntemin return deyimi yoksa veya işlenen döndürmeyen bir return deyimi varsa dönüş türü olarak kullanırsınız Task
.
Aşağıdaki örnekte , Task(Of TResult) veya Taskdöndüren bir yöntemi nasıl bildirdiğiniz ve çağırdığınız gösterilmektedir:
' Signature specifies Task(Of Integer)
Async Function TaskOfTResult_MethodAsync() As Task(Of Integer)
Dim hours As Integer
' . . .
' Return statement specifies an integer result.
Return hours
End Function
' Calls to TaskOfTResult_MethodAsync
Dim returnedTaskTResult As Task(Of Integer) = TaskOfTResult_MethodAsync()
Dim intResult As Integer = Await returnedTaskTResult
' or, in a single statement
Dim intResult As Integer = Await TaskOfTResult_MethodAsync()
' Signature specifies Task
Async Function Task_MethodAsync() As Task
' . . .
' The method has no return statement.
End Function
' Calls to Task_MethodAsync
Task returnedTask = Task_MethodAsync()
Await returnedTask
' or, in a single statement
Await Task_MethodAsync()
Döndürülmüş her görev, devam eden bir çalışmayı temsil eder. Bir görev, zaman uyumsuz işlemin durumu hakkındaki bilgileri saklar ve sonunda, işlemden alınan nihai sonuca veya başarısız olursa işlemin neden olduğu bir özel duruma ilişkin bilgileri içerir.
Zaman uyumsuz bir yöntem de bir Sub
yöntem olabilir. Bu dönüş türü öncelikle bir dönüş türünün gerekli olduğu olay işleyicilerini tanımlamak için kullanılır. Zaman uyumsuz olay işleyicileri, genellikle zaman uyumsuz programlar için başlangıç noktası olarak hizmet eder.
Yordam olan zaman uyumsuz bir Sub
yöntem beklenemez ve çağıran, yöntemin oluşturacağı özel durumları yakalayamaz.
Zaman uyumsuz bir yöntem ByRef parametrelerini bildiremez, ancak yöntemi bu tür parametrelere sahip yöntemleri çağırabilir.
Daha fazla bilgi ve örnekler için bkz. Zaman Uyumsuz Dönüş Türleri (Visual Basic). Zaman uyumsuz yöntemlerde özel durumları yakalama hakkında daha fazla bilgi için bkz . Deneyin... Yakalamak... Finally Deyimi.
Windows Çalışma Zamanı programlamadaki zaman uyumsuz API'ler, görevlere benzer şekilde aşağıdaki dönüş türlerinden birine sahiptir:
- Task(Of TResult) öğesine karşılık gelen IAsyncOperation(Of TResult)
- IAsyncActionöğesine karşılık gelen Task
- IAsyncActionWithProgress(Of TProgress)
- IAsyncOperationWithProgress(Of TResult, TProgress)
Daha fazla bilgi ve örnek için bkz. C# dilinde zaman uyumsuz API'leri çağırma veya Visual Basic.
Adlandırma kuralı
Kurala göre, değiştiricisi olan Async
yöntemlerin adlarına "Async" eklersiniz.
Bir olay, taban sınıf veya arabirim sözleşmesi farklı bir ad öneriyorsa kuralı yoksayabilirsiniz. Örneğin, gibi Button1_Click
yaygın olay işleyicilerini yeniden adlandırmamalısınız.
İlgili konular ve örnekler (Visual Studio)
Tam Örnek
Aşağıdaki kod, bu konuda ele alınan Windows Presentation Foundation (WPF) uygulamasındaki MainWindow.xaml.vb dosyasıdır. Örneği Zaman Uyumsuz Örnek: "Async ve Await ile Zaman Uyumsuz Programlama" örneğinden indirebilirsiniz.
Imports System.Net.Http
' Example that demonstrates Asynchronous Progamming with Async and Await.
' It uses HttpClient.GetStringAsync to download the contents of a website.
' Sample Output:
' Working . . . . . . .
'
' Length of the downloaded string: 39678.
Class MainWindow
' Mark the event handler with Async so you can use Await in it.
Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)
' Call and await immediately.
' StartButton_Click suspends until AccessTheWebAsync is done.
Dim contentLength As Integer = Await AccessTheWebAsync()
ResultsTextBox.Text &= $"{vbCrLf}Length of the downloaded string: {contentLength}.{vbCrLf}"
End Sub
' Three things to note about writing an Async Function:
' - The function has an Async modifier.
' - Its return type is Task or Task(Of T). (See "Return Types" section.)
' - As a matter of convention, its name ends in "Async".
Async Function AccessTheWebAsync() As Task(Of Integer)
Using client As New HttpClient()
' Call and await separately.
' - AccessTheWebAsync can do other things while GetStringAsync is also running.
' - getStringTask stores the task we get from the call to GetStringAsync.
' - Task(Of String) means it is a task which returns a String when it is done.
Dim getStringTask As Task(Of String) =
client.GetStringAsync("https://docs.microsoft.com/dotnet")
' You can do other work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork()
' The Await operator suspends AccessTheWebAsync.
' - AccessTheWebAsync does not continue until getStringTask is complete.
' - Meanwhile, control returns to the caller of AccessTheWebAsync.
' - Control resumes here when getStringTask is complete.
' - The Await operator then retrieves the String result from getStringTask.
Dim urlContents As String = Await getStringTask
' The Return statement specifies an Integer result.
' A method which awaits AccessTheWebAsync receives the Length value.
Return urlContents.Length
End Using
End Function
Sub DoIndependentWork()
ResultsTextBox.Text &= $"Working . . . . . . .{vbCrLf}"
End Sub
End Class