Zaman Uyumsuz Programlarda Denetim Akışı (Visual Basic)
ve Await
anahtar sözcüklerini kullanarak Async
zaman uyumsuz programları daha kolay yazabilir ve koruyabilirsiniz. Ancak, programınızın nasıl çalıştığını anlamıyorsanız sonuçlar sizi şaşırtabilir. Bu konu, denetim bir yöntemden diğerine geçtiğinde ve her seferinde hangi bilgilerin aktarıldığını göstermek için basit bir zaman uyumsuz program aracılığıyla denetim akışını izler.
Not
Async
ve Await
anahtar sözcükleri Visual Studio 2012'de kullanıma sunulmuştur.
Genel olarak, zaman uyumsuz kod içeren yöntemleri Zaman Uyumsuz değiştirici ile işaretlersiniz. Zaman uyumsuz değiştiriciyle işaretlenmiş bir yöntemde, yöntemin zaman uyumsuz olarak adlandırılan işlemin tamamlanmasını bekleyeceği yeri belirtmek için Await (Visual Basic) işlecini kullanabilirsiniz. Daha fazla bilgi için bkz . Async ve Await (Visual Basic) ile Zaman Uyumsuz Programlama.
Aşağıdaki örnek, belirtilen web sitesinin içeriğini dize olarak indirmek ve dizenin uzunluğunu görüntülemek için zaman uyumsuz yöntemler kullanır. Örnek aşağıdaki iki yöntemi içerir.
startButton_Click
öğesini çağırıpAccessTheWebAsync
sonucu görüntüler.AccessTheWebAsync
, bir web sitesinin içeriğini dize olarak indirir ve dizenin uzunluğunu döndürür.AccessTheWebAsync
, içeriğini indirmek için zaman uyumsuz HttpClient bir yöntemi GetStringAsync(String)kullanır.
Numaralandırılmış görüntüleme satırları, programın nasıl çalıştığını anlamanıza ve işaretlenen her noktada ne olduğunu açıklamanıza yardımcı olmak için program genelinde stratejik noktalarda görünür. Görüntü satırları "BİR" ile "ALTI" arasında etiketlenir. Etiketler, programın bu kod satırlarına ulaşma sırasını temsil eder.
Aşağıdaki kodda programın ana hattı gösterilmektedir.
Class MainWindow
Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs) Handles StartButton.Click
' ONE
Dim getLengthTask As Task(Of Integer) = AccessTheWebAsync()
' FOUR
Dim contentLength As Integer = Await getLengthTask
' SIX
ResultsTextBox.Text &=
vbCrLf & $"Length of the downloaded string: {contentLength}." & vbCrLf
End Sub
Async Function AccessTheWebAsync() As Task(Of Integer)
' TWO
Dim client As HttpClient = New HttpClient()
Dim getStringTask As Task(Of String) =
client.GetStringAsync("https://learn.microsoft.com")
' THREE
Dim urlContents As String = Await getStringTask
' FIVE
Return urlContents.Length
End Function
End Class
Etiketli konumların her biri , "BİR" ile "ALTI" arasında programın geçerli durumu hakkındaki bilgileri görüntüler. Aşağıdaki çıktı üretilir:
ONE: Entering startButton_Click.
Calling AccessTheWebAsync.
TWO: Entering AccessTheWebAsync.
Calling HttpClient.GetStringAsync.
THREE: Back in AccessTheWebAsync.
Task getStringTask is started.
About to await getStringTask & return a Task<int> to startButton_Click.
FOUR: Back in startButton_Click.
Task getLengthTask is started.
About to await getLengthTask -- no caller to return to.
FIVE: Back in AccessTheWebAsync.
Task getStringTask is complete.
Processing the return statement.
Exiting from AccessTheWebAsync.
SIX: Back in startButton_Click.
Task getLengthTask is finished.
Result from AccessTheWebAsync is stored in contentLength.
About to display contentLength and exit.
Length of the downloaded string: 33946.
Program Ayarlama
Bu konunun kullandığı kodu MSDN'den indirebilir veya kendiniz oluşturabilirsiniz.
Not
Örneği çalıştırmak için bilgisayarınızda Visual Studio 2012 veya üzeri ve .NET Framework 4.5 veya daha yeni bir sürümü yüklü olmalıdır.
Programı indirin
Bu konu için uygulamayı Zaman Uyumsuz Örnek: Zaman Uyumsuz Programlarda Denetim Akışı'ndan indirebilirsiniz. Aşağıdaki adımlar programı açar ve çalıştırır.
İndirilen dosyanın sıkıştırmasını açın ve Visual Studio'yu başlatın.
Menü çubuğunda Dosya, Aç, Proje/Çözüm'e tıklayın.
Sıkıştırması açılmış örnek kodun bulunduğu klasöre gidin, çözüm (.sln) dosyasını açın ve projeyi derlemek ve çalıştırmak için F5 anahtarını seçin.
Programı Kendiniz Oluşturun
Aşağıdaki Windows Presentation Foundation (WPF) projesi bu konu için kod örneğini içerir.
Projeyi çalıştırmak için aşağıdaki adımları uygulayın:
Visual Studio’yu çalıştırın.
Menü çubuğunda Dosya, Yeni, Proje'yi seçin.
Yeni Proje iletişim kutusu açılır.
Yüklü Şablonlar bölmesinde Visual Basic'i ve ardından proje türleri listesinden WPF Uygulaması'nı seçin.
Projenin adı olarak girin
AsyncTracer
ve tamam düğmesini seçin.Yeni proje Çözüm Gezgini görüntülenir.
Visual Studio Code Düzenleyicisi'nde MainWindow.xaml sekmesini seçin.
Sekme görünmüyorsa, Çözüm Gezgini'de MainWindow.xaml kısayol menüsünü açın ve kodu görüntüle'yi seçin.
MainWindow.xaml dosyasının XAML görünümünde kodu aşağıdaki kodla değiştirin.
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="MainWindow" Title="Control Flow Trace" Height="350" Width="525"> <Grid> <Button x:Name="StartButton" Content="Start" HorizontalAlignment="Left" Margin="221,10,0,0" VerticalAlignment="Top" Width="75"/> <TextBox x:Name="ResultsTextBox" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Bottom" Width="510" Height="265" FontFamily="Lucida Console" FontSize="10" VerticalScrollBarVisibility="Visible" d:LayoutOverrides="HorizontalMargin"/> </Grid> </Window>
MainWindow.xaml dosyasının Tasarım görünümünde metin kutusu ve düğme içeren basit bir pencere görüntülenir.
için System.Net.Httpbir başvuru ekleyin.
Çözüm Gezgini'da, MainWindow.xaml.vb kısayol menüsünü açın ve kodu görüntüle'yi seçin.
MainWindow.xaml.vb içinde kodu aşağıdaki kodla değiştirin.
' Add an Imports statement and a reference for System.Net.Http. Imports System.Net.Http Class MainWindow Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs) Handles StartButton.Click ' The display lines in the example lead you through the control shifts. ResultsTextBox.Text &= "ONE: Entering StartButton_Click." & vbCrLf & " Calling AccessTheWebAsync." & vbCrLf Dim getLengthTask As Task(Of Integer) = AccessTheWebAsync() ResultsTextBox.Text &= vbCrLf & "FOUR: Back in StartButton_Click." & vbCrLf & " Task getLengthTask is started." & vbCrLf & " About to await getLengthTask -- no caller to return to." & vbCrLf Dim contentLength As Integer = Await getLengthTask ResultsTextBox.Text &= vbCrLf & "SIX: Back in StartButton_Click." & vbCrLf & " Task getLengthTask is finished." & vbCrLf & " Result from AccessTheWebAsync is stored in contentLength." & vbCrLf & " About to display contentLength and exit." & vbCrLf ResultsTextBox.Text &= String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, contentLength) End Sub Async Function AccessTheWebAsync() As Task(Of Integer) ResultsTextBox.Text &= vbCrLf & "TWO: Entering AccessTheWebAsync." ' Declare an HttpClient object. Dim client As HttpClient = New HttpClient() ResultsTextBox.Text &= vbCrLf & " Calling HttpClient.GetStringAsync." & vbCrLf ' GetStringAsync returns a Task(Of String). Dim getStringTask As Task(Of String) = client.GetStringAsync("https://learn.microsoft.com") ResultsTextBox.Text &= vbCrLf & "THREE: Back in AccessTheWebAsync." & vbCrLf & " Task getStringTask is started." ' AccessTheWebAsync can continue to work until getStringTask is awaited. ResultsTextBox.Text &= vbCrLf & " About to await getStringTask & return a Task(Of Integer) to StartButton_Click." & vbCrLf ' Retrieve the website contents when task is complete. Dim urlContents As String = Await getStringTask ResultsTextBox.Text &= vbCrLf & "FIVE: Back in AccessTheWebAsync." & vbCrLf & " Task getStringTask is complete." & vbCrLf & " Processing the return statement." & vbCrLf & " Exiting from AccessTheWebAsync." & vbCrLf Return urlContents.Length End Function End Class
Programı çalıştırmak için F5 tuşunu seçin ve ardından Başlat düğmesini seçin.
Aşağıdaki çıkış görünmelidir:
ONE: Entering startButton_Click. Calling AccessTheWebAsync. TWO: Entering AccessTheWebAsync. Calling HttpClient.GetStringAsync. THREE: Back in AccessTheWebAsync. Task getStringTask is started. About to await getStringTask & return a Task<int> to startButton_Click. FOUR: Back in startButton_Click. Task getLengthTask is started. About to await getLengthTask -- no caller to return to. FIVE: Back in AccessTheWebAsync. Task getStringTask is complete. Processing the return statement. Exiting from AccessTheWebAsync. SIX: Back in startButton_Click. Task getLengthTask is finished. Result from AccessTheWebAsync is stored in contentLength. About to display contentLength and exit. Length of the downloaded string: 33946.
Programı İzleme
1. ve 2. Adımlar
İlk iki görüntüleme satırı yolu çağrısı olarak startButton_Click
izler ve AccessTheWebAsync
zaman uyumsuz HttpClient yöntemini GetStringAsync(String)AccessTheWebAsync
çağırır. Aşağıdaki görüntüde yöntemden yönteme çağrılar özetlenmiştir.
her ikisinin AccessTheWebAsync
de dönüş türü ve client.GetStringAsync
değeridir Task<TResult>. için AccessTheWebAsync
, TResult bir tamsayıdır. için GetStringAsync
, TResult bir dizedir. Zaman uyumsuz yöntem dönüş türleri hakkında daha fazla bilgi için bkz . Zaman Uyumsuz Dönüş Türleri (Visual Basic).
Görev döndüren bir zaman uyumsuz yöntem, denetim çağırana geri kaydığında bir görev örneği döndürür. Denetim, çağrılan yöntemde bir işleçle karşılaşıldığında veya çağrılan yöntem sona erdiğinde zaman uyumsuz bir Await
yöntemden çağırana döndürür. "ÜÇ" ile "ALTI" arasında etiketlenen görüntüleme çizgileri, işlemin bu bölümünü izler.
ÜÇ. Adım
içinde AccessTheWebAsync
, hedef web sayfasının içeriğini indirmek için zaman uyumsuz yöntem GetStringAsync(String) çağrılır. Denetim, döndürdüğünde'den'e client.GetStringAsync
AccessTheWebAsync
client.GetStringAsync
döner.
yöntemi, client.GetStringAsync
içindeki AccessTheWebAsync
değişkenine getStringTask
atanmış bir dize görevi döndürür. Örnek programdaki aşağıdaki satırda çağrısı client.GetStringAsync
ve atama gösterilir.
Dim getStringTask As Task(Of String) = client.GetStringAsync("https://learn.microsoft.com")
Sonunda gerçek bir dize oluşturarak client.GetStringAsync
görevi bir vaat olarak düşünebilirsiniz. Bu arada, bunu yapmak için gereken bir iş varsa AccessTheWebAsync
, söz verilen dizeye client.GetStringAsync
bağlı değildir. Bu işlem beklerken client.GetStringAsync
devam edebilir. Örnekte, "ÜÇ" etiketli aşağıdaki çıkış satırları, bağımsız çalışma yapma fırsatını temsil eder
THREE: Back in AccessTheWebAsync.
Task getStringTask is started.
About to await getStringTask & return a Task<int> to startButton_Click.
Aşağıdaki deyim, beklendiğinde getStringTask
ilerleme durumunu AccessTheWebAsync
askıya alır.
Dim urlContents As String = Await getStringTask
Aşağıdaki görüntüde, öğesinin oluşturulmasından getStringTask
Await işlecinin uygulamasına atamaya getStringTask
kadar olan denetim client.GetStringAsync
akışı gösterilmektedir.
Await ifadesi dönene kadar client.GetStringAsync
askıya alınıyorAccessTheWebAsync
. Bu arada, denetim öğesini çağırana AccessTheWebAsync
startButton_Click
geri döner.
Not
Genellikle, zaman uyumsuz bir yönteme çağrıyı hemen beklersiniz. Örneğin, aşağıdaki atama oluşturan ve ardından bekleyen getStringTask
önceki kodun yerini alabilir: Dim urlContents As String = Await client.GetStringAsync("https://learn.microsoft.com")
Bu konuda, await işleci daha sonra program aracılığıyla denetim akışını işaretleyen çıkış satırlarını barındırmak için uygulanır.
DÖRDÜNCÜ Adım
bildirilen dönüş türü AccessTheWebAsync
: Task(Of Integer)
. Bu nedenle, askıya alındığında AccessTheWebAsync
, için tamsayılık startButton_Click
bir görev döndürür. Döndürülen görevin olmadığını getStringTask
anlamalısınız. Döndürülen görev, askıya alınan yönteminde AccessTheWebAsync
yapılması gerekenleri temsil eden yeni bir tamsayı görevidir. Görev, görev tamamlandığında tamsayı üretmeye yönelik bir sözdür AccessTheWebAsync
.
Aşağıdaki deyim bu görevi değişkenine getLengthTask
atar.
Dim getLengthTask As Task(Of Integer) = AccessTheWebAsync()
içinde AccessTheWebAsync
olduğu gibi, startButton_Click
görev bekleninceye kadar zaman uyumsuz görevin (getLengthTask
) sonuçlarına bağlı olmayan çalışmaya devam edebilir. Aşağıdaki çıkış satırları bu çalışmayı temsil ediyor:
FOUR: Back in startButton_Click.
Task getLengthTask is started.
About to await getLengthTask -- no caller to return to.
startButton_Click
İlerleme durumu beklendiğinde getLengthTask
askıya alınır. Aşağıdaki atama deyimi tamamlanana kadar AccessTheWebAsync
askıya alınıyorstartButton_Click
.
Dim contentLength As Integer = Await getLengthTask
Aşağıdaki çizimde, oklar içindeki AccessTheWebAsync
await ifadesinden değerine bir değerin atanması için denetim akışını ve ardından beklenene getLengthTask
kadar getLengthTask
içinde startButton_Click
normal işlemeyi gösterir.
BEŞ. Adım
İşlemin tamamlandığının sinyalleri verildiğinde client.GetStringAsync
, içinde işleme AccessTheWebAsync
askıya alınmadan serbest bırakılır ve await deyimini aşmaya devam edebilir. Aşağıdaki çıkış satırları işlemenin yeniden başlatılmasını temsil ediyor:
FIVE: Back in AccessTheWebAsync.
Task getStringTask is complete.
Processing the return statement.
Exiting from AccessTheWebAsync.
return deyiminin işleneni, urlContents.Length
döndüren AccessTheWebAsync
görevde depolanır. await ifadesi bu değeri içinden getLengthTask
startButton_Click
alır.
Aşağıdaki görüntüde ( ve getStringTask
) tamamlandıktan sonra client.GetStringAsync
denetimin aktarımı gösterilmektedir.
AccessTheWebAsync
tamamlanmaya kadar çalışır ve denetim tamamlanmayı startButton_Click
bekleyen öğesine döner.
ALTı. Adım
İşlemin tamamlandığının sinyallerini aldığınızda AccessTheWebAsync
işleme, içindeki startButton_Async
await deyiminden sonra da devam edebilir. Aslında, programın yapacak başka bir şeyi yok.
Aşağıdaki çıkış satırları, içindeki startButton_Async
işlemenin yeniden başlatılmasını temsil ediyor:
SIX: Back in startButton_Click.
Task getLengthTask is finished.
Result from AccessTheWebAsync is stored in contentLength.
About to display contentLength and exit.
await ifadesi içindeki return deyiminin AccessTheWebAsync
işleneni olan tamsayı değerinden alırgetLengthTask
. Aşağıdaki deyim bu değeri değişkene contentLength
atar.
Dim contentLength As Integer = Await getLengthTask
Aşağıdaki görüntüde denetimin 'den öğesine AccessTheWebAsync
döndürülmesi startButton_Click
gösterilmektedir.