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 Async és Await 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.

Megjegyzés:

A Async és Await kulcsszavakat a Visual Studio 2012-ben vezették be.

Á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 jön létre:

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.

Megjegyzé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 Presentation Foundation (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 a Megoldáskezelőben.

  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őben, 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őben 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-ben 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

A kijelző első két sora nyomon követi az utat, ahol a startButton_Click hívja a AccessTheWebAsync-t, és a AccessTheWebAsync meghívja az aszinkron HttpClient metódust, a GetStringAsync(String)-t. Az alábbi képen a metódusról metódusra irányuló hívások láthatóak.

Lépések EGY és KETTŐ

A AccessTheWebAsync és client.GetStringAsync visszatérési típusa Task<TResult>. A AccessTheWebAsyncTResult egy egész szám. A GetStringAsync TResult egy karakterlánc. 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és az aszinkron metódusból akkor tér vissza a hívóhoz, amikor a hívott metódusban egy Await operátorhoz ér, vagy amikor a hívott metódus véget ér. A "THREE" és a "SIX" feliratú megjelenítési vonalak a folyamat ezen részét követik nyomon.

HARMADIK lépé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és a client.GetStringAsync-ról AccessTheWebAsync-re tér vissza, amikor a client.GetStringAsync visszatér.

A client.GetStringAsync metódus visszaad egy feladatot, amely egy sztringet ad vissza, és a(z) getStringTask változóhoz van hozzárendelve a AccessTheWebAsync-ben. 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 client.GetStringAsync ígéretére, hogy végül létrehoz egy tényleges sztringet. Amennyiben AccessTheWebAsync-nak/nak van olyan teendője, amely nem függ client.GetStringAsync ígért sztringjétől, ezt a munkát folytatni lehet, miközben client.GetStringAsync várakozik. A példában a következő, "HÁROM" címkével ellátott kimeneti sorok jelentik 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ását, amikor getStringTask-re vár.

Dim urlContents As String = Await getStringTask

Az alábbi képen a vezérlés áramlása látható client.GetStringAsync-től a getStringTask-hez való hozzárendelésig, valamint a getStringTask létrehozásától a Várakozás operátor alkalmazásáig.

HARMADIK lépés

A várakozási kifejezés felfüggesztve marad AccessTheWebAsync , amíg client.GetStringAsync nem tér vissza. Közben a vezérlő visszatér a AccessTheWebAsync, startButton_Click hívójához.

Megjegyzé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, amikor a AccessTheWebAsync fel van függesztve, egész szám feladatot ad vissza a startButton_Click számára. 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 egy ígéret arra, AccessTheWebAsync hogy egész számot szolgáltat 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 Továbbra is folytathatja azokat a munkákat, 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.

A startButton_Click előrehaladás felfüggesztésre kerül, amikor getLengthTask várakozik. A következő hozzárendelési utasítás startButton_Click felfüggesztésre kerül, amíg AccessTheWebAsync be nem fejeződik.

Dim contentLength As Integer = Await getLengthTask

Az alábbi ábrán a nyilak az await kifejezéstől AccessTheWebAsync az érték getLengthTask hozzárendeléséig tartó vezérlés áramlását mutatják, amelyet a normál feldolgozás startButton_Click követ, amíg a getLengthTask várakozás bekövetkezik.

FOUR. lépés

ÖTÖDIK lépés

Ha client.GetStringAsync azt jelzi, hogy befejeződött, a AccessTheWebAsync-beli feldolgozás felszabadul a felfüggesztés alól, és folytatódhat az await utasítás után. 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 tárolódik. A várakozási kifejezés lekéri ezt az értéket a(z) getLengthTask elemről startButton_Click.

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

ÖTÖDIK LÉPÉS

AccessTheWebAsync a befejezésig fut, és a vezérlés visszatér a startButton_Click-hoz, amely a befejezésre vár.

6. lépés

Ha AccessTheWebAsync jelzi, hogy a művelet befejeződött, a feldolgozás a várakozási utasításon túl is folytatódhat startButton_Async-ben. 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 getLengthTask-ből lekérdezi azt az egész értéket, amely a visszatérési utasítás AccessTheWebAsync operandusa. 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és AccessTheWebAsync-ről startButton_Click-re történő visszatérése látható.

HAT. lépés

Lásd még