Partager via


Types de retour asynchrones (Visual Basic)

Les méthodes asynchrones ont trois types de retour possibles : Task<TResult>, Tasket void. Dans Visual Basic, le type de retour void est écrit en tant que sous-procédure . Pour plus d’informations sur les méthodes asynchrones, consultez Programmation asynchrone avec Async et Await (Visual Basic).

Chaque type de retour est examiné dans l’une des sections suivantes, et vous trouverez un exemple complet qui utilise les trois types à la fin de la rubrique.

Remarque

Pour exécuter l’exemple, vous devez disposer de Visual Studio 2012 ou version ultérieure et du .NET Framework 4.5 ou ultérieur installé sur votre ordinateur.

Type de retour Task(T)

Le Task<TResult> type de retour est utilisé pour une méthode asynchrone qui contient une instruction Return dans laquelle l’opérande a le type TResult.

Dans l’exemple suivant, la TaskOfT_MethodAsync méthode asynchrone contient une instruction return qui retourne un entier. Par conséquent, la déclaration de méthode doit spécifier un type de retour 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

Lorsqu’elle TaskOfT_MethodAsync est appelée à partir d’une expression await, l’expression await récupère la valeur entière (la valeur de leisureHours) stockée dans la tâche retournée par TaskOfT_MethodAsync. Pour plus d’informations sur les expressions Await, consultez l’opérateur Await.

Les appels de code suivants et la méthode TaskOfT_MethodAsyncawaits . Le résultat est affecté à la result1 variable.

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

Vous pouvez mieux comprendre comment cela se produit en séparant l’appel de TaskOfT_MethodAsync l’application , Awaitcomme le montre le code suivant. Un appel à la méthode TaskOfT_MethodAsync qui n’est pas immédiatement attendue retourne un type Task(Of Integer), comme vous pourriez l’attendre de la déclaration de la méthode. La tâche est affectée à la variable integerTask dans l’exemple. Étant donné que integerTask est un Task<TResult>, il contient une propriété Result de type TResult. Dans ce cas, TResult représente un type entier. Quand Await est appliqué à integerTask, l’expression await prend pour la valeur le contenu de la propriété Result de integerTask. La valeur est affectée à la variable result2.

Avertissement

Result est une propriété bloquante. Si vous essayez d’y accéder avant la fin de sa tâche, le thread actuellement actif est bloqué jusqu’à ce que la tâche se termine et que la valeur soit disponible. Dans la plupart des cas, vous devez accéder à la valeur avec Await au lieu d’accéder directement à la propriété.

' 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

Les instructions d’affichage dans le code suivant vérifient que les valeurs de la result1 variable, de la result2 variable et de la Result propriété sont identiques. N’oubliez pas que la Result propriété est une propriété bloquante et qu’elle ne doit pas être accessible avant que sa tâche n’ait été attendue.

' 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

Type de retour de tâche

Les méthodes asynchrones qui ne contiennent pas d’instruction return ou qui contiennent une instruction return qui ne retourne pas d’opérande ont généralement un type de Taskretour . Ces méthodes sont des sous-procédures si elles ont été écrites pour s’exécuter de manière synchrone. Si vous utilisez un Task type de retour pour une méthode asynchrone, une méthode appelante peut utiliser un Await opérateur pour suspendre l’achèvement de l’appelant jusqu’à ce que la méthode asynchrone appelée ait terminé.

Dans l’exemple suivant, la méthode Task_MethodAsync asynchrone ne contient pas d’instruction return. Par conséquent, vous spécifiez un type de retour pour Task la méthode, qui permet Task_MethodAsync d’être attendu. La définition du Task type n’inclut pas de Result propriété pour stocker une valeur de retour.

' 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 est appelé et attendu à l’aide d’une instruction await au lieu d’une expression await, similaire à l’instruction appelante pour une méthode synchrone Sub ou void-return. L’application d’un Await opérateur dans ce cas ne produit pas de valeur.

Les appels de code suivants et la méthode Task_MethodAsyncawaits .

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

Comme dans l’exemple précédent Task<TResult> , vous pouvez séparer l’appel de Task_MethodAsync l’application d’un Await opérateur, comme le montre le code suivant. Toutefois, n’oubliez pas qu’une Task n’a pas de propriété Result et qu’aucune valeur n’est produite lorsqu’un opérateur Await est appliqué à un Task.

Le code suivant sépare l’appel Task_MethodAsync de l’attente de la tâche qui Task_MethodAsync retourne.

' 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

Type de retour Void

L’utilisation principale des procédures se trouve dans les gestionnaires d’événements Sub , où il n’existe aucun type de retour (appelé type de retour void dans d’autres langues). Un retour void peut également être utilisé pour remplacer les méthodes de retour void ou pour les méthodes qui effectuent des activités qui peuvent être classées comme « fire and forget ». Toutefois, vous devez retourner une Task valeur dans la mesure du possible, car une méthode asynchrone void-return ne peut pas être attendue. Tout appelant de cette méthode doit pouvoir continuer à se terminer sans attendre que la méthode asynchrone appelée se termine, et l’appelant doit être indépendant de toutes les valeurs ou exceptions générées par la méthode asynchrone.

L’appelant d’une méthode asynchrone de retour void ne peut pas intercepter les exceptions levées à partir de la méthode, et ces exceptions non gérées risquent de provoquer l’échec de votre application. Si une exception se produit dans une méthode asynchrone qui retourne une Task ou Task<TResult>, l’exception est stockée dans la tâche retournée et se développe à nouveau lorsque la tâche est attendue. Par conséquent, assurez-vous que toute méthode asynchrone pouvant produire une exception a un type de retour ou TaskTask<TResult> que les appels à la méthode sont attendus.

Pour plus d’informations sur la façon d’intercepter des exceptions dans des méthodes asynchrones, consultez Try...Catch...Finally Statement.

Le code suivant définit un gestionnaire d’événements asynchrone.

' 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

Exemple complet

Le projet WPF (Windows Presentation Foundation) suivant contient les exemples de code de cette rubrique.

Pour exécuter le projet, procédez comme suit :

  1. Démarrez Visual Studio.

  2. Dans le menu principal, sélectionnez Fichier, Nouveau, Projet.

    La boîte de dialogue Nouveau projet s’ouvre.

  3. Dans la catégorie Installé, Modèles , choisissez Visual Basic, puis Windows. Choisissez Application WPF dans la liste des types de projets.

  4. Entrez AsyncReturnTypes le nom du projet, puis choisissez le bouton OK .

    Le nouveau projet s’affiche dans l’Explorateur de solutions.

  5. Dans l'éditeur de code Visual Studio, choisissez l'onglet MainWindow.xaml .

    Si l’onglet n’est pas visible, ouvrez le menu contextuel de MainWindow.xaml dans l’Explorateur de solutions, puis choisissez Ouvrir.

  6. Dans la fenêtre XAML de MainWindow.xaml, remplacez le code par le code suivant.

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

    Une fenêtre simple qui contient une zone de texte et un bouton s’affiche dans la fenêtre Création de MainWindow.xaml.

  7. Dans l’Explorateur de solutions, ouvrez le menu contextuel pour MainWindow.xaml.vb, puis choisissez Afficher le code.

  8. Remplacez le code dans MainWindow.xaml.vb par le code suivant.

    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. Appuyez sur la touche F5 pour exécuter le programme, puis choisissez le bouton Démarrer.

    La sortie suivante doit apparaître :

    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.
    

Voir aussi