Tipos de retorno assíncronos (Visual Basic)
Os métodos assíncronos têm três tipos de retorno possíveis: Task<TResult>, Taske void. No Visual Basic, o tipo de retorno void é escrito como um procedimento Sub . Para obter mais informações sobre métodos assíncronos, consulte Programação assíncrona com Async e Await (Visual Basic).
Cada tipo de retorno é examinado em uma das seções a seguir, e você pode encontrar um exemplo completo que usa todos os três tipos no final do tópico.
Nota
Para executar o exemplo, você deve ter o Visual Studio 2012 ou mais recente e o .NET Framework 4.5 ou mais recente instalado no seu computador.
Tipo de retorno Task(T)
O Task<TResult> tipo de retorno é usado para um método assíncrono que contém uma instrução Return na qual o operando tem tipo TResult
.
No exemplo a seguir, o TaskOfT_MethodAsync
método async contém uma instrução return que retorna um inteiro. Portanto, a declaração de método deve especificar um tipo de retorno de 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
Quando TaskOfT_MethodAsync
é chamada de dentro de uma expressão await, a expressão await recupera o valor inteiro (o valor de ) armazenado na tarefa retornada leisureHours
pelo TaskOfT_MethodAsync
. Para obter mais informações sobre expressões await, consulte Await Operator.
O código a seguir chama e aguarda o método TaskOfT_MethodAsync
. O resultado é atribuído à result1
variável.
' Call and await the Task(Of T)-returning async method in the same statement.
Dim result1 As Integer = Await TaskOfT_MethodAsync()
Você pode entender melhor como isso acontece separando a chamada para TaskOfT_MethodAsync
do aplicativo do Await
, como mostra o código a seguir. Uma chamada para o método TaskOfT_MethodAsync
que não é imediatamente aguardada retorna um Task(Of Integer)
, como você esperaria da declaração do método. A tarefa é atribuída à integerTask
variável no exemplo. Porque integerTask
é um Task<TResult>, ele contém uma Result propriedade do tipo TResult
. Neste caso, TResult representa um tipo inteiro. Quando Await
é aplicada ao integerTask
, a expressão await é avaliada para o conteúdo da Result propriedade de integerTask
. O valor é atribuído à result2
variável.
Aviso
A Result propriedade é uma propriedade de bloqueio. Se você tentar acessá-lo antes que sua tarefa seja concluída, o thread que está ativo no momento será bloqueado até que a tarefa seja concluída e o valor esteja disponível. Na maioria dos casos, você deve acessar o valor usando Await
em vez de acessar a propriedade diretamente.
' 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
As instruções display no código a seguir verificam se os valores da result1
variável, da result2
variável e da Result
propriedade são os mesmos. Lembre-se de que a Result
propriedade é uma propriedade de bloqueio e não deve ser acessada antes que sua tarefa seja aguardada.
' 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
Tipo de Retorno de Tarefa
Os métodos assíncronos que não contêm uma instrução return ou que contêm uma instrução return que não retorna um operando geralmente têm um tipo de retorno de Task. Tais métodos seriam procedimentos Sub se fossem escritos para serem executados de forma síncrona. Se você usar um Task
tipo de retorno para um método assíncrono, um método de chamada poderá usar um Await
operador para suspender a conclusão do chamador até que o método assíncrono chamado seja concluído.
No exemplo a seguir, o método Task_MethodAsync
async não contém uma instrução return. Portanto, você especifica um tipo de retorno de Task
para o método, que permite Task_MethodAsync
ser aguardado. A definição do tipo não inclui uma Result
propriedade para armazenar um valor de Task
retorno.
' 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
é chamado e aguardado usando uma instrução await em vez de uma expressão await, semelhante à instrução calling para um método síncrono Sub
ou de retorno de vazio. A aplicação de um Await
operador, neste caso, não produz um valor.
O código a seguir chama e aguarda o método Task_MethodAsync
.
' Call and await the Task-returning async method in the same statement.
Await Task_MethodAsync()
Como no exemplo anterior Task<TResult> , você pode separar a chamada para Task_MethodAsync
do aplicativo de um Await
operador, como mostra o código a seguir. No entanto, lembre-se de que um Task
não tem uma Result
propriedade e que nenhum valor é produzido quando um operador de espera é aplicado a um Task
.
O código a seguir separa a chamada Task_MethodAsync
da espera da tarefa que Task_MethodAsync
retorna.
' 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
Tipo de retorno vazio
O principal uso de procedimentos é em manipuladores de eventos, onde não há nenhum tipo de retorno (referido como um tipo de Sub
retorno vazio em outros idiomas). Um retorno de vazio também pode ser usado para substituir métodos de retorno de vazio ou para métodos que executam atividades que podem ser categorizadas como "fogo e esquecimento". No entanto, você deve retornar um Task
sempre que possível, porque um método assíncrono de retorno de vazio não pode ser aguardado. Qualquer chamador de tal método deve ser capaz de continuar a conclusão sem esperar que o método assíncrono chamado termine, e o chamador deve ser independente de quaisquer valores ou exceções que o método assíncrono gera.
O chamador de um método assíncrono de retorno de vazio não pode capturar exceções que são lançadas do método, e essas exceções não tratadas provavelmente farão com que seu aplicativo falhe. Se ocorrer uma exceção em um método assíncrono que retorna um Task ou Task<TResult>, a exceção será armazenada na tarefa retornada e relançada quando a tarefa for aguardada. Portanto, certifique-se de que qualquer método assíncrono que possa produzir uma exceção tenha um tipo de retorno de Task ou Task<TResult> e que as chamadas para o método sejam aguardadas.
Para obter mais informações sobre como capturar exceções em métodos assíncronos, consulte Tentar... Pegar... Finalmente Declaração.
O código a seguir define um manipulador de eventos assíncrono.
' 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
Exemplo completo
O seguinte projeto do Windows Presentation Foundation (WPF) contém os exemplos de código deste tópico.
Para executar o projeto, execute as seguintes etapas:
Inicie o Visual Studio.
Na barra de menus, escolha Arquivo, Novo, Projeto.
A caixa de diálogo Novo projeto é aberta.
Na categoria Modelos instalados, escolhaVisual Basic e, em seguida, escolha Windows. Escolha Aplicativo WPF na lista de tipos de projeto.
Digite
AsyncReturnTypes
como o nome do projeto e, em seguida, escolha o botão OK .O novo projeto aparece no Gerenciador de Soluções.
No Editor de Códigos do Visual Studio, escolha a guia MainWindow.xaml .
Se a guia não estiver visível, abra o menu de atalho para MainWindow.xaml no Gerenciador de Soluções e escolha Abrir.
Na janela XAML de MainWindow.xaml, substitua o código pelo código a seguir.
<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>
Uma janela simples que contém uma caixa de texto e um botão aparece na janela Design de MainWindow.xaml.
No Gerenciador de Soluções, abra o menu de atalho para MainWindow.xaml.vb e escolha Exibir Código.
Substitua o código no MainWindow.xaml.vb pelo código a seguir.
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
Escolha a tecla F5 para executar o programa e, em seguida, escolha o botão Iniciar .
A seguinte saída deve aparecer:
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.
Consulte também
Comentários
https://aka.ms/ContentUserFeedback.
Brevemente: Ao longo de 2024, vamos descontinuar progressivamente o GitHub Issues como mecanismo de feedback para conteúdos e substituí-lo por um novo sistema de feedback. Para obter mais informações, veja:Submeter e ver comentários