Megosztás a következőn keresztül:


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ívja AccessTheWebAsync é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.

  1. Bontsa ki a letöltött fájlt, majd indítsa el a Visual Studiót.

  2. A menüsávon válassza a Fájl, Megnyitás, Projekt/Megoldás lehetőséget.

  3. 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:

  1. Indítsa el a Visual Studiót.

  2. A menüsávon válassza a Fájl, Új, Projekt lehetőséget.

    Megnyílik az Új projekt párbeszédpanel.

  3. 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.

  4. Adja meg AsyncTracer a projekt nevét, majd kattintson az OK gombra.

    Az új projekt megjelenik Megoldáskezelő.

  5. 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.

  6. 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.

  7. Adjon hozzá egy hivatkozást a következőhöz System.Net.Http: .

  8. A Megoldáskezelő nyissa meg a MainWindow.xaml.vb helyi menüjét, majd válassza a Kód megtekintése lehetőséget.

  9. 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
    
  10. 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_ClickAccessTheWebAsyncnyomon 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.

Steps ONE and TWO

A visszatérési típus mindkettőAccessTheWebAsync, és client.GetStringAsync az .Task<TResult> A AccessTheWebAsyncTResult egy egész szám. A GetStringAsyncTResult 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 AccessTheWebAsyncaz 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.GetStringAsyncAccessTheWebAsyncclient.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

Step THREE

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_Clickhí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 getStringTaskkó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 AccessTheWebAsyncTask(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()

AccessTheWebAsyncstartButton_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 getLengthTaskhozzá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.

Step FOUR

Ö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.Lengthoperandusa a visszaadott AccessTheWebAsync feladatban lesz tárolva. A várakozási kifejezés lekéri ezt az értéket a következőből getLengthTaskstartButton_Click: .

Az alábbi képen a vezérlő átvitele látható, miután client.GetStringAsync (és getStringTask) befejeződött.

Step FIVE

AccessTheWebAsync a befejezésig fut, és a startButton_Clickvezé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 AccessTheWebAsyncoperandusá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ő AccessTheWebAsyncstartButton_Clickvisszatérése látható.

Step SIX

Lásd még