Delen via


Asynchrone retourtypen (Visual Basic)

Asynchrone methoden hebben drie mogelijke retourtypen: Task<TResult>, Tasken void. In Visual Basic wordt het retourtype ongeldigheid geschreven als een subprocedure . Zie Asynchrone programmering met Asynchroon programmeren met Async en Await (Visual Basic) voor meer informatie over asynchrone methoden.

Elk retourtype wordt onderzocht in een van de volgende secties en u vindt een volledig voorbeeld waarin alle drie de typen aan het einde van het onderwerp worden gebruikt.

Notitie

Als u het voorbeeld wilt uitvoeren, moet Visual Studio 2012 of hoger en .NET Framework 4.5 of hoger op uw computer zijn geïnstalleerd.

Retourtype taak(T)

Het Task<TResult> retourtype wordt gebruikt voor een asynchrone methode die een Return-instructie bevat waarin de operand het type TResultheeft.

In het volgende voorbeeld bevat de TaskOfT_MethodAsync asynchrone methode een retourinstructie die een geheel getal retourneert. Daarom moet de methodedeclaratie een retourtype van Task(Of Integer)opgeven.

' 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

Wanneer TaskOfT_MethodAsync wordt aangeroepen vanuit een await-expressie, haalt de await-expressie de gehele waarde (de waarde van leisureHours) op die is opgeslagen in de taak die wordt geretourneerd door TaskOfT_MethodAsync. Zie Await Operator voor meer informatie over await-expressies.

De volgende code roept de methode aan en wacht op de methode TaskOfT_MethodAsync. Het resultaat wordt toegewezen aan de result1 variabele.

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

U kunt beter begrijpen hoe dit gebeurt door de aanroep te TaskOfT_MethodAsync scheiden van de toepassing van Await, zoals in de volgende code wordt weergegeven. Een aanroep naar de methode TaskOfT_MethodAsync die niet onmiddellijk wordt gewacht, retourneert een Task(Of Integer), zoals u zou verwachten uit de declaratie van de methode. De taak wordt toegewezen aan de integerTask variabele in het voorbeeld. Omdat integerTask is een Task<TResult>, het bevat een Result eigenschap van het type TResult. In dit geval vertegenwoordigt TResult een geheel getaltype. Wanneer Await deze wordt toegepast integerTaskop, wordt de await-expressie geëvalueerd op de inhoud van de Result eigenschap van integerTask. De waarde wordt toegewezen aan de result2 variabele.

Waarschuwing

De Result eigenschap is een blokkerende eigenschap. Als u deze probeert te openen voordat de taak is voltooid, wordt de thread die momenteel actief is geblokkeerd totdat de taak is voltooid en de waarde beschikbaar is. In de meeste gevallen moet u toegang krijgen tot de waarde door deze te gebruiken Await in plaats van rechtstreeks toegang te krijgen tot de eigenschap.

' 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

De weergave-instructies in de volgende code controleren of de waarden van de result1 variabele, de result2 variabele en de Result eigenschap hetzelfde zijn. Houd er rekening mee dat de Result eigenschap een blokkerende eigenschap is en niet moet worden geopend voordat de taak wordt verwacht.

' 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

Retourtype taak

Asynchrone methoden die geen retourinstructie bevatten of die een retourinstructie bevatten die geen operand retourneert, hebben meestal een retourtype Task. Dergelijke methoden zouden subprocedures zijn als ze synchroon werden geschreven. Als u een Task retourtype gebruikt voor een asynchrone methode, kan een aanroepmethode een Await operator gebruiken om de voltooiing van de aanroeper op te schorten totdat de aangeroepen asynchrone methode is voltooid.

In het volgende voorbeeld bevat de asynchrone methode Task_MethodAsync geen retourinstructie. Daarom geeft u een retourtype voor Task de methode op, waarmee Task_MethodAsync kan worden gewacht. De definitie van het Task type bevat Result geen eigenschap voor het opslaan van een retourwaarde.

' 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 wordt aangeroepen en gewacht met behulp van een await-instructie in plaats van een await-expressie, vergelijkbaar met de aanroepinstructie voor een synchrone Sub of ongeldige retourmethode. De toepassing van een Await operator in dit geval produceert geen waarde.

De volgende code roept de methode aan en wacht op de methode Task_MethodAsync.

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

Net als in het vorige Task<TResult> voorbeeld kunt u de aanroep Task_MethodAsync scheiden van de toepassing van een Await operator, zoals in de volgende code wordt weergegeven. Houd er echter rekening mee dat een Task eigenschap niet heeft Result en dat er geen waarde wordt geproduceerd wanneer een wachtoperator wordt toegepast op een Task.

Met de volgende code wordt het aanroepen Task_MethodAsync gescheiden van het wachten op de taak die Task_MethodAsync wordt geretourneerd.

' 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

Ongeldig retourtype

Het primaire gebruik van Sub procedures is in gebeurtenis-handlers, waarbij er geen retourtype is (ook wel een ongeldig retourtype in andere talen genoemd). Een ongeldige retour kan ook worden gebruikt om ongeldige retourmethoden te overschrijven of voor methoden die activiteiten uitvoeren die kunnen worden gecategoriseerd als 'fire and forget'. U moet echter een waar mogelijk resultaat Task geven, omdat er geen asynchrone asynchrone methode kan worden verwacht. Elke aanroeper van een dergelijke methode moet kunnen doorgaan tot voltooiing zonder te wachten tot de aangeroepen asynchrone methode is voltooid en de aanroeper moet onafhankelijk zijn van waarden of uitzonderingen die door de asynchrone methode worden gegenereerd.

De aanroeper van een ongeldige asynchrone methode kan geen uitzonderingen onderscheppen die worden gegenereerd uit de methode en dergelijke niet-verwerkte uitzonderingen veroorzaken waarschijnlijk dat uw toepassing mislukt. Als er een uitzondering optreedt in een asynchrone methode die een Task of Task<TResult>retourneert, wordt de uitzondering opgeslagen in de geretourneerde taak en wordt deze opnieuw geplaatst wanneer de taak wordt verwacht. Zorg er daarom voor dat elke asynchrone methode die een uitzondering kan produceren, een retourtype Task heeft of Task<TResult> dat aanroepen naar de methode worden gewacht.

Zie Proberen voor meer informatie over het vangen van uitzonderingen in asynchrone methoden ... Vangen... Tot slot verklaring.

De volgende code definieert een asynchrone gebeurtenis-handler.

' 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

Volledig voorbeeld

Het volgende WPF-project (Windows Presentation Foundation) bevat de codevoorbeelden uit dit onderwerp.

Voer de volgende stappen uit om het project uit te voeren:

  1. Start Visual Studio.

  2. Kies Bestand, Nieuw, Project in de menubalk.

    Het dialoogvenster Nieuw project wordt geopend.

  3. Kies Visual Basic in de categorie Geïnstalleerd, Sjablonen en kies Vervolgens Windows. Kies WPF-toepassing in de lijst met projecttypen.

  4. Voer AsyncReturnTypes de naam van het project in en kies vervolgens de knop OK .

    Het nieuwe project wordt weergegeven in Solution Explorer.

  5. Kies in de Visual Studio Code-editor het tabblad MainWindow.xaml .

    Als het tabblad niet zichtbaar is, opent u het snelmenu voor MainWindow.xaml in Solution Explorer en kiest u Openen.

  6. Vervang in het venster XAML van MainWindow.xaml de code door de volgende code.

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

    Een eenvoudig venster met een tekstvak en een knop wordt weergegeven in het ontwerpvenster van MainWindow.xaml.

  7. Open in Solution Explorer het snelmenu voor MainWindow.xaml.vb en kies Code weergeven.

  8. Vervang de code in MainWindow.xaml.vb door de volgende code.

    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. Kies de F5-toets om het programma uit te voeren en kies vervolgens de knop Start .

    De volgende uitvoer moet worden weergegeven:

    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.
    

Zie ook