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 TResult
heeft.
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 integerTask
op, 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:
Start Visual Studio.
Kies Bestand, Nieuw, Project in de menubalk.
Het dialoogvenster Nieuw project wordt geopend.
Kies Visual Basic in de categorie Geïnstalleerd, Sjablonen en kies Vervolgens Windows. Kies WPF-toepassing in de lijst met projecttypen.
Voer
AsyncReturnTypes
de naam van het project in en kies vervolgens de knop OK .Het nieuwe project wordt weergegeven in Solution Explorer.
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.
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.
Open in Solution Explorer het snelmenu voor MainWindow.xaml.vb en kies Code weergeven.
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
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.