Folyamatvezérlés az Async-programokban (Visual Basic)
Aszinkron programokat könnyebben írhat és tarthat fenn a kulcsszavak és Await
a Async
kulcsszavak használatával. Az eredmények azonban meglephetik, ha nem érti a program működését. Ez a témakör egy egyszerű aszinkron programon keresztül nyomon követheti a vezérlőfolyamatot, amely megmutatja, hogy a vezérlő mikor lép át egyik módszerről a másikra, és milyen információkat továbbít minden alkalommal.
Feljegyzés
A Async
visual Studio 2012-ben bevezettük a kulcsszavakat és Await
a kulcsszavakat.
Általában az aszinkron kódot tartalmazó metódusokat jelöli meg az Async módosítóval. Az aszinkron módosítóval megjelölt metódusokban a Await (Visual Basic) operátorral megadhatja, hogy a metódus hol szünetel, amíg egy úgynevezett aszinkron folyamat befejeződik. További információ: Aszinkron programozás az Async és a Await (Visual Basic) használatával.
Az alábbi példa aszinkron metódusokkal tölti le egy megadott webhely tartalmát sztringként, és megjeleníti a sztring hosszát. A példa a következő két módszert tartalmazza.
startButton_Click
, amely meghívjaAccessTheWebAsync
és megjeleníti az eredményt.AccessTheWebAsync
, amely egy webhely tartalmát sztringként tölti le, és visszaadja a sztring hosszát.AccessTheWebAsync
A tartalom letöltéséhez aszinkron HttpClient metódust GetStringAsync(String)használ.
A számozott megjelenítési vonalak a program stratégiai pontjain jelennek meg, így könnyebben megértheti a program működését, és elmagyarázhatja, hogy mi történik az egyes megjelölt pontokon. A megjelenítési sorok "ONE" és "SIX" címkével vannak ellátva. A címkék azt a sorrendet jelölik, amelyben a program eléri ezeket a kódsorokat.
Az alábbi kód a program vázlatát mutatja be.
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
Az "EGY" és a "HAT" címkével ellátott helyek mindegyike a program aktuális állapotával kapcsolatos információkat jeleníti meg. A következő kimenet lesz előállítva:
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.
A program beállítása
Letöltheti a témakör által használt kódot az MSDN-ből, vagy saját maga is létrehozhatja.
Feljegyzés
A példa futtatásához telepítve kell lennie a Visual Studio 2012-nek vagy újabbnak, valamint a .NET-keretrendszer 4.5-ös vagy újabb verziójának.
A program letöltése
A témakörhöz tartozó alkalmazást az Async Sample: Control Flow in Async Programs alkalmazásból töltheti le. Az alábbi lépések megnyitják és futtatják a programot.
Bontsa ki a letöltött fájlt, majd indítsa el a Visual Studiót.
A menüsávon válassza a Fájl, Megnyitás, Projekt/Megoldás lehetőséget.
Keresse meg a kibontott mintakódot tartalmazó mappát, nyissa meg a megoldásfájlt (.sln), majd válassza az F5 billentyűt a projekt létrehozásához és futtatásához.
Saját maga készítse el a programot
Az alábbi Windows megjelenítési alaprendszer (WPF) projekt a jelen témakör kód példáját tartalmazza.
A projekt futtatásához hajtsa végre a következő lépéseket:
Indítsa el a Visual Studiót.
A menüsávon válassza a Fájl, Új, Projekt lehetőséget.
Megnyílik az Új projekt párbeszédpanel.
A Telepített sablonok panelen válassza a Visual Basic, majd a WPF-alkalmazás lehetőséget a projekttípusok listájából.
Adja meg
AsyncTracer
a projekt nevét, majd kattintson az OK gombra.Az új projekt megjelenik Megoldáskezelő.
A Visual Studio Code Editorban válassza a MainWindow.xaml lapot.
Ha a lap nem látható, nyissa meg a MainWindow.xaml helyi menüjét a Megoldáskezelő, majd válassza a Kód megtekintése lehetőséget.
A MainWindow.xaml XAML nézetében cserélje le a kódot a következő kódra.
<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>
A MainWindow.xaml Tervező nézetében megjelenik egy egyszerű ablak, amely egy szövegdobozt és egy gombot tartalmaz.
Adjon hozzá egy hivatkozást a következőhöz System.Net.Http: .
A Megoldáskezelő nyissa meg a MainWindow.xaml.vb helyi menüjét, majd válassza a Kód megtekintése lehetőséget.
A MainWindow.xaml.vb cserélje le a kódot a következő kódra.
' 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
A program futtatásához válassza az F5 billentyűt, majd a Start gombot.
A következő kimenetnek kell megjelennie:
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.
A program nyomon követése
Első és második lépés
Az első két megjelenítési sor hívásként startButton_Click
AccessTheWebAsync
nyomon követheti az elérési utat, és AccessTheWebAsync
meghívja az aszinkron HttpClient metódust GetStringAsync(String). Az alábbi képen a metódusról metódusra irányuló hívások láthatóak.
A visszatérési típus mindkettőAccessTheWebAsync
, és client.GetStringAsync
az .Task<TResult> A AccessTheWebAsync
TResult egy egész szám. A GetStringAsync
TResult egy sztring. Az aszinkron metódus visszatérési típusairól további információt az Async Return Types (Visual Basic) című témakörben talál.
A feladatvisszaadó aszinkron metódus feladatpéldányt ad vissza, amikor a vezérlő visszakerül a hívóhoz. A vezérlő az aszinkron metódusból a hívójának ad vissza egy Await
operátort a hívott metódusban, vagy amikor a hívott metódus véget ér. A "THR Enterprise kiadás" címkével ellátott megjelenítési vonalak a folyamat ezen részét követik nyomon.
THR lépés Enterprise kiadás
Ebben AccessTheWebAsync
az esetben a rendszer meghívja az aszinkron metódust GetStringAsync(String) a célweboldal tartalmának letöltésére. A vezérlőelem a visszatérések időpontjára client.GetStringAsync
AccessTheWebAsync
client.GetStringAsync
tér vissza.
A client.GetStringAsync
metódus visszaad egy sztringfeladatot, amely a változóhoz van rendelve a getStringTask
következőben AccessTheWebAsync
: . A példaprogram következő sorában a hívás client.GetStringAsync
és a hozzárendelés látható.
Dim getStringTask As Task(Of String) = client.GetStringAsync("https://learn.microsoft.com")
Úgy tekinthet a feladatra, mint ígéretre client.GetStringAsync
, ha végül létrehoz egy tényleges sztringet. Addig is, ha AccessTheWebAsync
van teendője, az nem függ az ígért sztringtől client.GetStringAsync
, a munka várakozás közben client.GetStringAsync
is folytatódhat. A példában a következő, "THR Enterprise kiadás" címkével ellátott kimeneti sorok jelzik a lehetőséget, hogy önálló munkát végezzenek
THREE: Back in AccessTheWebAsync.
Task getStringTask is started.
About to await getStringTask & return a Task<int> to startButton_Click.
Az alábbi utasítás felfüggeszti az AccessTheWebAsync
előrehaladást, amikor getStringTask
a várakozásra vár.
Dim urlContents As String = Await getStringTask
Az alábbi képen a vezérlés folyamata látható a Várakozás operátor létrehozásának és alkalmazásának létrehozásától client.GetStringAsync
kezdve a hozzárendelésiggetStringTask
.getStringTask
A várakozási kifejezés mindaddig felfüggesztve marad AccessTheWebAsync
, amíg vissza nem client.GetStringAsync
tér. Addig is a vezérlő visszatér a ( ) startButton_Click
hívójáhozAccessTheWebAsync
.
Feljegyzés
Általában azonnal várja az aszinkron metódus hívását. A következő hozzárendelés például lecserélheti a korábban létrehozott és várt getStringTask
kódot: Dim urlContents As String = Await client.GetStringAsync("https://learn.microsoft.com")
Ebben a témakörben a várakozási operátort később alkalmazza a program a vezérlőfolyamatot a programon keresztül jelző kimeneti sorok elhelyezésére.
NEGYEDIK lépés
A deklarált visszatérési típus az AccessTheWebAsync
Task(Of Integer)
. Ezért ha AccessTheWebAsync
fel van függesztve, a függvény egész számból startButton_Click
álló feladatot ad vissza. Meg kell értenie, hogy a visszaadott feladat nem getStringTask
. A visszaadott feladat egy egész szám új feladata, amely a felfüggesztett metódusban még elvégzendő feladatokat jelöli. AccessTheWebAsync
A feladat ígéret arra, AccessTheWebAsync
hogy egész számot állít elő a tevékenység befejezésekor.
Az alábbi utasítás hozzárendeli ezt a feladatot a getLengthTask
változóhoz.
Dim getLengthTask As Task(Of Integer) = AccessTheWebAsync()
AccessTheWebAsync
startButton_Click
A továbbiakban is folytathatja azokat a munkát, amelyek nem függnek az aszinkron tevékenység (getLengthTask
) eredményeitől, amíg meg nem várják a feladatot. A következő kimeneti sorok jelölik a munkát:
FOUR: Back in startButton_Click.
Task getLengthTask is started.
About to await getLengthTask -- no caller to return to.
startButton_Click
A folyamat felfüggesztésre kerül, ha getLengthTask
a várakozásra vár. A következő hozzárendelési startButton_Click
utasítás mindaddig felfüggeszti a műveletet, amíg be nem AccessTheWebAsync
fejeződik.
Dim contentLength As Integer = Await getLengthTask
Az alábbi ábrán a nyilak a várt kifejezéstől AccessTheWebAsync
az érték getLengthTask
hozzárendeléséig tartó vezérlőfolyamatot mutatják, amelyet a normál feldolgozás startButton_Click
követ, amíg meg nem getLengthTask
vár.
ÖTÖDIK lépés
Ha client.GetStringAsync
azt jelzi, hogy a folyamat befejeződött, a feldolgozás AccessTheWebAsync
feloldódik a felfüggesztés alól, és továbbhaladhat a várakozási utasításon. A következő kimeneti sorok a feldolgozás újraindítását jelölik:
FIVE: Back in AccessTheWebAsync.
Task getStringTask is complete.
Processing the return statement.
Exiting from AccessTheWebAsync.
A visszatérési utasítás urlContents.Length
operandusa a visszaadott AccessTheWebAsync
feladatban lesz tárolva. A várakozási kifejezés lekéri ezt az értéket a következőből getLengthTask
startButton_Click
: .
Az alábbi képen a vezérlő átvitele látható, miután client.GetStringAsync
(és getStringTask
) befejeződött.
AccessTheWebAsync
a befejezésig fut, és a startButton_Click
vezérlő visszatér a befejezésre váró folyamathoz.
6. lépés
Ha AccessTheWebAsync
azt jelzi, hogy befejeződött, a feldolgozás továbbhaladhat a várakozási utasításon a következőben startButton_Async
: . Valójában a programnak nincs több teendője.
A következő kimeneti sorok a feldolgozás újrakezdését jelölik a következőben startButton_Async
:
SIX: Back in startButton_Click.
Task getLengthTask is finished.
Result from AccessTheWebAsync is stored in contentLength.
About to display contentLength and exit.
A várakozási kifejezés a visszatérési utasítás AccessTheWebAsync
operandusát tartalmazó egész számból getLengthTask
kér le. Az alábbi utasítás ezt az értéket rendeli hozzá a contentLength
változóhoz.
Dim contentLength As Integer = Await getLengthTask
Az alábbi ábrán a vezérlő AccessTheWebAsync
startButton_Click
visszatérése látható.