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


Aszinkron visszatérési típusok (Visual Basic)

Az aszinkron metódusoknak három lehetséges visszatérési típusuk van: Task<TResult>, Taskés üres. A Visual Basicben az üres visszatérési típus alműveletként van megírva. Az aszinkron módszerekkel kapcsolatos további információkért lásd : Aszinkron programozás az Async és a Await használatával (Visual Basic).

Az egyes visszatérési típusokat a következő szakaszok egyikében vizsgáljuk meg, és a témakör végén található mindhárom típust használó teljes példát talál.

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.

Tevékenység(T) visszatérési típusa

A Task<TResult> visszatérési típus egy olyan aszinkron metódushoz használatos, amely olyan Return utasítást tartalmaz, amelyben az operandus típusa TResultszerepel.

Az alábbi példában az aszinkron TaskOfT_MethodAsync metódus egy egész számot visszaadó visszatérési utasítást tartalmaz. Ezért a metódusdeklarációnak meg kell adnia a visszatérési típust Task(Of Integer).

' TASK(OF T) EXAMPLE
Async Function TaskOfT_MethodAsync() As Task(Of Integer)

    ' The body of an async method is expected to contain an awaited
    ' asynchronous call.
    ' Task.FromResult is a placeholder for actual work that returns a string.
    Dim today As String = Await Task.FromResult(Of String)(DateTime.Now.DayOfWeek.ToString())

    ' The method then can process the result in some way.
    Dim leisureHours As Integer
    If today.First() = "S" Then
        leisureHours = 16
    Else
        leisureHours = 5
    End If

    ' Because the return statement specifies an operand of type Integer, the
    ' method must have a return type of Task(Of Integer).
    Return leisureHours
End Function

Ha TaskOfT_MethodAsync egy várakozási kifejezésen belülről hívjuk meg, a várakozási kifejezés lekéri a feladat által visszaadott TaskOfT_MethodAsyncfeladatban tárolt egész számot (annak értékétleisureHours). A várakozási kifejezésekről további információt az Operátor várakozása című témakörben talál.

Az alábbi kódhívások és -várakozások metódusa TaskOfT_MethodAsync. Az eredmény hozzá van rendelve a result1 változóhoz.

' Call and await the Task(Of T)-returning async method in the same statement.
Dim result1 As Integer = Await TaskOfT_MethodAsync()

Jobban megértheti, hogy ez hogyan történik, ha elválasztja a hívást TaskOfT_MethodAsync az alkalmazástól Await, ahogyan az alábbi kód mutatja. A nem azonnal várt metódushívás TaskOfT_MethodAsync a metódus deklarációjától elvárható módon ad vissza egy Task(Of Integer)értéket. A feladat a példában a integerTask változóhoz van rendelve. Mivel integerTask ez egy Task<TResult>, egy típusú TResulttulajdonságot Result tartalmaz. Ebben az esetben a TResult egy egész számtípust jelöl. Amikor Await alkalmazva integerTaskvan, a várakozás kifejezés kiértékeli a Result tulajdonság integerTasktartalmát. Az érték hozzá van rendelve a result2 változóhoz.

Figyelmeztetés

A Result tulajdonság egy blokkoló tulajdonság. Ha a tevékenység befejezése előtt megpróbálja elérni, az aktuálisan aktív szál le lesz tiltva, amíg a tevékenység be nem fejeződik, és az érték elérhetővé válik. A legtöbb esetben a tulajdonság közvetlen elérése helyett az értékhez Await kell hozzáférnie.

' Call and await in separate statements.
Dim integerTask As Task(Of Integer) = TaskOfT_MethodAsync()

' You can do other work that does not rely on resultTask before awaiting.
textBox1.Text &= "Application can continue working while the Task(Of T) runs. . . . " & vbCrLf

Dim result2 As Integer = Await integerTask

Az alábbi kód megjelenítési utasításai ellenőrzik, hogy a result1 változó, a result2 változó és a Result tulajdonság értékei megegyeznek-e. Ne feledje, hogy a Result tulajdonság egy blokkoló tulajdonság, és nem szabad elérni, mielőtt a feladat várva lett volna.

' Display the values of the result1 variable, the result2 variable, and
' the resultTask.Result property.
textBox1.Text &= vbCrLf & $"Value of result1 variable:   {result1}" & vbCrLf
textBox1.Text &= $"Value of result2 variable:   {result2}" & vbCrLf
textBox1.Text &= $"Value of resultTask.Result:  {integerTask.Result}" & vbCrLf

Feladat visszaküldési típusa

Azok az aszinkron metódusok, amelyek nem tartalmaznak visszatérési utasítást, vagy olyan visszatérési utasítást tartalmaznak, amely nem ad vissza operandusokat, általában visszatérési típussal Taskrendelkeznek. Ezek a metódusok aleljárások lennének, ha szinkron futtatásra lennének írva. Ha egy aszinkron metódushoz visszatérési típust Task használ, a hívó metódus operátorral Await felfüggesztheti a hívó befejezését, amíg a hívott aszinkron metódus be nem fejeződik.

Az alábbi példában az aszinkron metódus Task_MethodAsync nem tartalmaz visszatérési utasítást. Ezért meg kell adnia a metódus visszatérési Task típusát, amely lehetővé teszi Task_MethodAsync a várakozást. A típus definíciója Task nem tartalmaz Result visszatérési értéket tároló tulajdonságot.

' TASK EXAMPLE
Async Function Task_MethodAsync() As Task

    ' The body of an async method is expected to contain an awaited
    ' asynchronous call.
    ' Task.Delay is a placeholder for actual work.
    Await Task.Delay(2000)
    textBox1.Text &= vbCrLf & "Sorry for the delay. . . ." & vbCrLf

    ' This method has no return statement, so its return type is Task.
End Function

Task_MethodAsync várakozási kifejezés helyett várakozási utasítással hívja meg és várja meg a rendszer, hasonlóan a szinkron Sub vagy üres visszatérési metódus hívási utasításához. Az operátor alkalmazása Await ebben az esetben nem eredményez értéket.

Az alábbi kódhívások és -várakozások metódusa Task_MethodAsync.

' Call and await the Task-returning async method in the same statement.
Await Task_MethodAsync()

Az előző Task<TResult> példához hasonlóan az operátor alkalmazásától Await is elkülönítheti a hívásokatTask_MethodAsync, ahogy az alábbi kód is mutatja. Ne feledje azonban, hogy a Task tulajdonság nem rendelkezik tulajdonságokkal Result , és hogy nem jön létre érték, amikor egy várakozási operátort alkalmaz egy Task.

Az alábbi kód elválasztja a hívásokat Task_MethodAsync a visszaadott feladatra Task_MethodAsync való várakozástól.

' Call and await in separate statements.
Dim simpleTask As Task = Task_MethodAsync()

' You can do other work that does not rely on simpleTask before awaiting.
textBox1.Text &= vbCrLf & "Application can continue working while the Task runs. . . ." & vbCrLf

Await simpleTask

Érvénytelen visszatérési típus

Az eljárások elsődleges használata Sub az eseménykezelőkben történik, ahol nincs visszatérési típus (más nyelveken érvénytelen visszatérési típusnak nevezzük). A semmis visszatérés használható az érvénytelen visszatérési módszerek felülbírálására, vagy olyan módszerekre is, amelyek olyan tevékenységeket végeznek, amelyek "tűz és felejtés" kategóriába sorolhatók. Ha azonban lehetséges, vissza kell adnia egy Task érvénytelenítő aszinkron metódust. Az ilyen metódus bármely hívójának képesnek kell lennie a befejezésre anélkül, hogy várnia kell a hívott aszinkron metódus befejezésére, és a hívónak függetlennek kell lennie az aszinkron metódus által létrehozott értékektől vagy kivételektől.

Az érvénytelenül visszaadott aszinkron metódus hívója nem tudja elkapni a metódusból kidobott kivételeket, és az ilyen kezeletlen kivételek valószínűleg az alkalmazás sikertelenségét okozzák. Ha kivétel történik egy aszinkron metódusban, amely egy vagy Task<TResult>több értéket ad visszaTask, a kivételt a visszaadott tevékenység tárolja, és a feladat várásakor újra megnő. Ezért győződjön meg arról, hogy minden kivételt okozó aszinkron metódus visszatérési Task típussal rendelkezik, és Task<TResult> hogy a metódus hívásai várakoznak.

További információ az aszinkron metódusok kivételeinek fogásáról: Kipróbálás... Fogás... Végül nyilatkozat.

Az alábbi kód egy aszinkron eseménykezelőt határoz meg.

' SUB EXAMPLE
Async Sub button1_Click(sender As Object, e As RoutedEventArgs) Handles button1.Click

    textBox1.Clear()

    ' Start the process and await its completion. DriverAsync is a
    ' Task-returning async method.
    Await DriverAsync()

    ' Say goodbye.
    textBox1.Text &= vbCrLf & "All done, exiting button-click event handler."
End Sub

Példa kitöltése

Az alábbi Windows megjelenítési alaprendszer (WPF) projekt a jelen témakörből származó kód példákat 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 kategóriában válassza a Visual Basic, majd a Windows lehetőséget. Válassza a WPF-alkalmazást a projekttípusok listájából.

  4. Adja meg AsyncReturnTypes 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 Megnyitás lehetőséget.

  6. A MainWindow.xaml XAML ablakában cserélje le a kódot a következő kódra.

    <Window x:Class="MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Button x:Name="button1" Content="Start" HorizontalAlignment="Left" Margin="214,28,0,0" VerticalAlignment="Top" Width="75" HorizontalContentAlignment="Center" FontWeight="Bold" FontFamily="Aharoni" Click="button1_Click"/>
            <TextBox x:Name="textBox1" Margin="0,80,0,0" TextWrapping="Wrap" FontFamily="Lucida Console"/>
    
        </Grid>
    </Window>
    

    A MainWindow.xaml tervezőablakában megjelenik egy egyszerű ablak, amely egy szövegdobozt és egy gombot tartalmaz.

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

  8. Cserélje le a MainWindow.xaml.vb kódját a következő kódra.

    Class MainWindow
    
        ' SUB EXAMPLE
        Async Sub button1_Click(sender As Object, e As RoutedEventArgs) Handles button1.Click
    
            textBox1.Clear()
    
            ' Start the process and await its completion. DriverAsync is a
            ' Task-returning async method.
            Await DriverAsync()
    
            ' Say goodbye.
            textBox1.Text &= vbCrLf & "All done, exiting button-click event handler."
        End Sub
    
        Async Function DriverAsync() As Task
    
            ' Task(Of T)
            ' Call and await the Task(Of T)-returning async method in the same statement.
            Dim result1 As Integer = Await TaskOfT_MethodAsync()
    
            ' Call and await in separate statements.
            Dim integerTask As Task(Of Integer) = TaskOfT_MethodAsync()
    
            ' You can do other work that does not rely on resultTask before awaiting.
            textBox1.Text &= "Application can continue working while the Task(Of T) runs. . . . " & vbCrLf
    
            Dim result2 As Integer = Await integerTask
    
            ' Display the values of the result1 variable, the result2 variable, and
            ' the resultTask.Result property.
            textBox1.Text &= vbCrLf & $"Value of result1 variable:   {result1}" & vbCrLf
            textBox1.Text &= $"Value of result2 variable:   {result2}" & vbCrLf
            textBox1.Text &= $"Value of resultTask.Result:  {integerTask.Result}" & vbCrLf
    
            ' Task
            ' Call and await the Task-returning async method in the same statement.
            Await Task_MethodAsync()
    
            ' Call and await in separate statements.
            Dim simpleTask As Task = Task_MethodAsync()
    
            ' You can do other work that does not rely on simpleTask before awaiting.
            textBox1.Text &= vbCrLf & "Application can continue working while the Task runs. . . ." & vbCrLf
    
            Await simpleTask
        End Function
    
        ' TASK(OF T) EXAMPLE
        Async Function TaskOfT_MethodAsync() As Task(Of Integer)
    
            ' The body of an async method is expected to contain an awaited
            ' asynchronous call.
            ' Task.FromResult is a placeholder for actual work that returns a string.
            Dim today As String = Await Task.FromResult(Of String)(DateTime.Now.DayOfWeek.ToString())
    
            ' The method then can process the result in some way.
            Dim leisureHours As Integer
            If today.First() = "S" Then
                leisureHours = 16
            Else
                leisureHours = 5
            End If
    
            ' Because the return statement specifies an operand of type Integer, the
            ' method must have a return type of Task(Of Integer).
            Return leisureHours
        End Function
    
        ' TASK EXAMPLE
        Async Function Task_MethodAsync() As Task
    
            ' The body of an async method is expected to contain an awaited
            ' asynchronous call.
            ' Task.Delay is a placeholder for actual work.
            Await Task.Delay(2000)
            textBox1.Text &= vbCrLf & "Sorry for the delay. . . ." & vbCrLf
    
            ' This method has no return statement, so its return type is Task.
        End Function
    
    End Class
    
  9. A program futtatásához válassza az F5 billentyűt, majd a Start gombot.

    A következő kimenetnek kell megjelennie:

    Application can continue working while the Task<T> runs. . . .
    
    Value of result1 variable:   5
    Value of result2 variable:   5
    Value of integerTask.Result: 5
    
    Sorry for the delay. . . .
    
    Application can continue working while the Task runs. . . .
    
    Sorry for the delay. . . .
    
    All done, exiting button-click event handler.
    

Lásd még