Asynchroniczne typy zwracane (Visual Basic)
Metody asynchroniczne mają trzy możliwe typy zwracane: Task<TResult>, Taski void. W języku Visual Basic zwracany typ void jest zapisywany jako procedura podrzędna. Aby uzyskać więcej informacji na temat metod asynchronicznych, zobacz Asynchroniczne programowanie za pomocą Async i Await (Visual Basic).
Każdy typ zwracany jest badany w jednej z poniższych sekcji i można znaleźć pełny przykład, który używa wszystkich trzech typów na końcu tematu.
Uwaga
Aby uruchomić przykład, na komputerze musi być zainstalowany program Visual Studio 2012 lub nowszy oraz program .NET Framework 4.5 lub nowszy.
Typ zwracany zadania (T)
Zwracany Task<TResult> typ jest używany dla metody asynchronicznej zawierającej instrukcję Return , w której operand ma typ TResult
.
W poniższym przykładzie TaskOfT_MethodAsync
metoda async zawiera instrukcję return zwracającą liczbę całkowitą. W związku z tym deklaracja metody musi określać typ zwracany .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
Gdy TaskOfT_MethodAsync
jest wywoływana z wewnątrz wyrażenia await, wyrażenie await pobiera wartość całkowitą (wartość leisureHours
) przechowywaną w zadaniu zwracanym przez TaskOfT_MethodAsync
element . Aby uzyskać więcej informacji na temat wyrażeń await, zobacz Await Operator.
Następujące wywołania kodu i metoda awaits TaskOfT_MethodAsync
. Wynik jest przypisywany do zmiennej result1
.
' Call and await the Task(Of T)-returning async method in the same statement.
Dim result1 As Integer = Await TaskOfT_MethodAsync()
Możesz lepiej zrozumieć, jak to się dzieje, oddzielając wywołanie TaskOfT_MethodAsync
od aplikacji Await
, jak pokazano w poniższym kodzie. Wywołanie metody TaskOfT_MethodAsync
, która nie jest natychmiast oczekiwana, zwraca metodę Task(Of Integer)
, jak można oczekiwać od deklaracji metody. Zadanie jest przypisywane do zmiennej integerTask
w przykładzie. Ponieważ integerTask
jest elementem Task<TResult>, zawiera Result właściwość typu TResult
. W tym przypadku funkcja TResult reprezentuje typ liczby całkowitej. Gdy Await
jest stosowany do integerTask
elementu , wyrażenie await oblicza zawartość Result właściwości integerTask
. Wartość jest przypisywana do zmiennej result2
.
Ostrzeżenie
Właściwość Result jest właściwością blokującą. Jeśli spróbujesz uzyskać dostęp do niego przed zakończeniem jego zadania, wątek, który jest obecnie aktywny, zostanie zablokowany do momentu zakończenia zadania i będzie dostępna wartość. W większości przypadków należy uzyskać dostęp do wartości przy użyciu metody Await
zamiast bezpośrednio uzyskiwać dostęp do właściwości.
' 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
Instrukcje wyświetlania w poniższym kodzie sprawdzają, czy wartości result1
zmiennej, result2
zmiennej i Result
właściwości są takie same. Należy pamiętać, że Result
właściwość jest właściwością blokującą i nie powinna być dostępna przed oczekiwaniem na jego zadanie.
' 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
Typ zwracanego zadania
Metody asynchroniczne, które nie zawierają instrukcji return lub które zawierają instrukcję return, która nie zwraca operandu, zwykle ma typ Taskzwracany . Takie metody byłyby procedurami podrzędnych , gdyby zostały napisane w celu synchronicznego uruchamiania. Jeśli używasz typu zwracanego Task
dla metody asynchronicznej, metoda wywołująca może użyć Await
operatora do wstrzymania ukończenia obiektu wywołującego do momentu zakończenia wywoływanej metody asynchronicznej.
W poniższym przykładzie metoda Task_MethodAsync
async nie zawiera instrukcji return. W związku z tym należy określić typ zwracany Task
dla metody, która umożliwia oczekiwanie Task_MethodAsync
. Definicja Task
typu nie zawiera Result
właściwości do przechowywania wartości zwracanej.
' 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
metoda jest wywoływana i oczekiwana przy użyciu instrukcji await zamiast wyrażenia await, podobnie jak instrukcja wywołująca dla metody synchronicznej Sub
lub zwracanej przez void. Zastosowanie Await
operatora w tym przypadku nie powoduje wygenerowania wartości.
Następujące wywołania kodu i metoda awaits Task_MethodAsync
.
' Call and await the Task-returning async method in the same statement.
Await Task_MethodAsync()
Tak jak w poprzednim Task<TResult> przykładzie, można oddzielić wywołanie od Task_MethodAsync
aplikacji Await
operatora, jak pokazano w poniższym kodzie. Należy jednak pamiętać, że obiekt Task
nie ma Result
właściwości i że żadna wartość nie jest generowany, gdy operator await jest stosowany do obiektu Task
.
Poniższy kod oddziela wywołanie Task_MethodAsync
od oczekiwania na zwracane zadanie 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
Typ powrotu void
Podstawowym zastosowaniem Sub
procedur jest obsługa zdarzeń, gdzie nie ma zwracanego typu (nazywanego typem zwracanym void w innych językach). Zwracanie pustki może również służyć do zastępowania metod zwracania pustki lub metod, które wykonują działania, które można podzielić na "ogień i zapomnieć". Jednak należy zwrócić Task
wszędzie tam, gdzie to możliwe, ponieważ nie można oczekiwać metody asynchronicznej zwracającej wartość void. Każdy obiekt wywołujący taką metodę musi być w stanie kontynuować uzupełnianie bez oczekiwania na zakończenie wywoływanej metody asynchronicznej, a obiekt wywołujący musi być niezależny od wszelkich wartości lub wyjątków generowanych przez metodę asynchroniową.
Obiekt wywołujący metody asynchronicznej nie może przechwytywać wyjątków zgłaszanych z metody, a takie nieobsługiwane wyjątki mogą spowodować niepowodzenie aplikacji. Jeśli wyjątek występuje w metodzie asynchronicznej, która zwraca wartość Task lub Task<TResult>, wyjątek jest przechowywany w zwracanym zadaniu i jest ponownie zwracany, gdy zadanie jest oczekiwane. W związku z tym upewnij się, że każda metoda asynchronizna, która może wygenerować wyjątek, ma zwracany typ Task lub Task<TResult> i że oczekuje się wywołań do metody.
Aby uzyskać więcej informacji na temat przechwytywania wyjątków w metodach asynchronicznych, zobacz Try... Złapać... Finally, instrukcja.
Poniższy kod definiuje asynchroniczny program obsługi zdarzeń.
' 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
Kompletny przykład
Poniższy projekt Windows Presentation Foundation (WPF) zawiera przykłady kodu z tego tematu.
Aby uruchomić projekt, wykonaj następujące kroki:
Uruchom program Visual Studio.
Na pasku menu wybierz pozycję Plik, Nowy, Projekt.
Zostanie otwarte okno dialogowe Nowy projekt .
W kategorii Zainstalowane szablony wybierz pozycję Visual Basic, a następnie wybierz pozycję Windows. Wybierz pozycję Aplikacja WPF z listy typów projektów.
Wprowadź
AsyncReturnTypes
jako nazwę projektu, a następnie wybierz przycisk OK .Nowy projekt zostanie wyświetlony w Eksplorator rozwiązań.
W edytorze programu Visual Studio Code wybierz kartę MainWindow.xaml .
Jeśli karta nie jest widoczna, otwórz menu skrótów dla pliku MainWindow.xaml w Eksplorator rozwiązań, a następnie wybierz pozycję Otwórz.
W oknie XAML pliku MainWindow.xaml zastąp kod poniższym kodem.
<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>
Proste okno zawierające pole tekstowe i przycisk pojawi się w oknie Projekt w pliku MainWindow.xaml.
W Eksplorator rozwiązań otwórz menu skrótów dla MainWindow.xaml.vb, a następnie wybierz pozycję Wyświetl kod.
Zastąp kod w MainWindow.xaml.vb następującym kodem.
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
Wybierz klawisz F5, aby uruchomić program, a następnie wybierz przycisk Uruchom .
Powinny zostać wyświetlone następujące dane wyjściowe:
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.
Zobacz też
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla