Partager via


Avertissement du compilateur (niveau 1) CS4014

Dans la mesure où cet appel n'est pas attendu, l'exécution de la méthode actuelle continue avant la fin de l'appel.Envisagez d'appliquer l'opérateur 'await' au résultat de l'appel.

Les appels de méthode actuels une méthode async qui retourne Task ou Task<TResult> et n'implémente pas l'opérateur d' attendez au résultat.L'appel à la méthode async lance une tâche asynchrone.Toutefois, car aucun opérateur d' await n'est appliqué, le programme se poursuit sans attendre la tâche soit terminée.Dans la plupart des cas, n'est pas ce comportement que vous attendez.Généralement d'autres aspects de la méthode d'appel dépendent des résultats de l'appel ou, de façon minimum, est censée la méthode appelée se termine avant de retourniez de la méthode qui contient l'appel.

Un problème également importante est ce qui arrive à des exceptions déclenchées dans la méthode appelée async.Une exception qui est levée dans une méthode qui retourne Task ou Task<TResult> est stockée dans la tâche retournée.Si vous n'attendez pas la tâche ou ne vérifiez pas explicitement les exceptions, l'exception est perdue.Si vous attendez une tâche, l'exception est à nouveau levée.

Comme meilleure pratique, vous devez toujours attendre l'appel.

Vous devez envisager de supprimer l'avertissement uniquement si vous êtes certain que vous ne souhaitez pas attendre l'appel asynchrone se termine et que la méthode appelée ne lève pas d'exception.Dans ce cas, vous pouvez supprimer l'avertissement en assignant le résultat de la tâche de l'appel à une variable.

L'exemple suivant montre comment générer l'avertissement, comment le supprimer, et comment attendre l'appel.

async Task CallingMethodAsync()
{
    resultsTextBox.Text += "\r\n  Entering calling method.";
    // Variable delay is used to slow down the called method so that you can
    // distinguish between awaiting and not awaiting in the program's output.
    // You can adjust the value to produce the output that this topic shows
    // after the code.
    var delay = 5000;

    // Call #1.
    // Call an async method. Because you don't await it, its completion 
    // isn't coordinated with the current method, CallingMethodAsync.
    // The following line causes warning CS4014.
    CalledMethodAsync(delay);

    // Call #2.
    // To suppress the warning without awaiting, you can assign the 
    // returned task to a variable. The assignment doesn't change how
    // the program runs. However, recommended practice is always to
    // await a call to an async method.

    // Replace Call #1 with the following line.
    //Task delayTask = CalledMethodAsync(delay);

    // Call #3
    // To contrast with an awaited call, replace the unawaited call 
    // (Call #1 or Call #2) with the following awaited call. Best 
    // practice is to await the call.

    //await CalledMethodAsync(delay);

    // If the call to CalledMethodAsync isn't awaited, CallingMethodAsync
    // continues to run and, in this example, finishes its work and returns
    // to its caller.
    resultsTextBox.Text += "\r\n  Returning from calling method.";
}


async Task CalledMethodAsync(int howLong)
{
    resultsTextBox.Text += 
        "\r\n    Entering called method, starting and awaiting Task.Delay.";

    // Slow the process down a little so that you can distinguish between
    // awaiting and not awaiting in the program's output. Adjust the value
    // for howLong if necessary.
    await Task.Delay(howLong);
    resultsTextBox.Text += 
        "\r\n    Task.Delay is finished--returning from called method.";
}

Dans l'exemple, si vous choisissez l'appel n°1 ou appelez n°2, la fin unawaited de méthode async (CalledMethodAsync) après son appelant (CallingMethodAsync) et l'appelant de l'appel (startButton_Click) sont terminées.La dernière ligne de la sortie suivante indique une fois la méthode appelée se termine.L'entrée et la sortie du gestionnaire d'événements qui appelle CallingMethodAsync dans l'exemple complet sont marquées dans la sortie.

Entering the Click event handler.
  Entering calling method.
    Entering called method, starting and awaiting Task.Delay.
  Returning from calling method.
Exiting the Click event handler.
    Task.Delay is finished--returning from called method.

Vous pouvez également supprimer les avertissements du compilateur en utilisant les directives de #pragma warning (référence C#) .

Exemple

L'application suivante Windows Presentation Foundation (WPF) contient les méthodes de l'exemple précédent.Les étapes suivantes ont installé l'application.

  1. Créer une application WPF, et nommez -la AsyncWarning.

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

    Si l'onglet n'est pas visible, ouvrez le menu contextuel pour MainWindow.xaml dans Explorateur de solutions, puis choisissez Afficher le code.

  3. Remplacez le code dans la vue XAML pour MainWindow.xaml par le code suivant.

    <Window x:Class="AsyncWarning.MainWindow"
            xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Button x:Name="startButton" Content="Start" HorizontalAlignment="Left" Margin="214,28,0,0" VerticalAlignment="Top" Width="75" HorizontalContentAlignment="Center" FontWeight="Bold" FontFamily="Aharoni" Click="startButton_Click" />
            <TextBox x:Name="resultsTextBox" Margin="0,80,0,0" TextWrapping="Wrap" FontFamily="Lucida Console"/>
        </Grid>
    </Window>
    

    Une fenêtre simple qui contient un bouton et une zone de texte apparaît dans la vue Design MainWindow.xaml.

    Pour plus d'informations sur le concepteur XAML, consultez Création d'une interface utilisateur à l'aide du concepteur XAML.Pour plus d'informations sur la génération de votre propre interface utilisateur simple, consultez « pour créer une application WPF » et « de concevoir des sections WPF un MainWindow simple » de Procédure pas à pas : accès au Web avec Async et Await (C# et Visual Basic).

  4. Remplacez le code dans MainWindow.xaml.cs par le code suivant.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace AsyncWarning
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private async void startButton_Click(object sender, RoutedEventArgs e)
            {
                resultsTextBox.Text += "\r\nEntering the Click event handler.";
                await CallingMethodAsync();
                resultsTextBox.Text += "\r\nExiting the Click event handler.";
            }
    
    
            async Task CallingMethodAsync()
            {
                resultsTextBox.Text += "\r\n  Entering calling method.";
                // Variable delay is used to slow down the called method so that you can
                // distinguish between awaiting and not awaiting in the program's output.
                // You can adjust the value to produce the output that this topic shows
                // after the code.
                var delay = 5000;
    
                // Call #1.
                // Call an async method. Because you don't await it, its completion 
                // isn't coordinated with the current method, CallingMethodAsync.
                // The following line causes warning CS4014.
                CalledMethodAsync(delay);
    
                // Call #2.
                // To suppress the warning without awaiting, you can assign the 
                // returned task to a variable. The assignment doesn't change how
                // the program runs. However, recommended practice is always to
                // await a call to an async method.
    
                // Replace Call #1 with the following line.
                //Task delayTask = CalledMethodAsync(delay);
    
                // Call #3
                // To contrast with an awaited call, replace the unawaited call 
                // (Call #1 or Call #2) with the following awaited call. Best 
                // practice is to await the call.
    
    
                //await CalledMethodAsync(delay);
    
                // If the call to CalledMethodAsync isn't awaited, CallingMethodAsync
                // continues to run and, in this example, finishes its work and returns
                // to its caller.
                resultsTextBox.Text += "\r\n  Returning from calling method.";
            }
    
    
            async Task CalledMethodAsync(int howLong)
            {
                resultsTextBox.Text += 
                    "\r\n    Entering called method, starting and awaiting Task.Delay.";
    
                // Slow the process down a little so that you can distinguish between
                // awaiting and not awaiting in the program's output. Adjust the value
                // for howLong if necessary.
                await Task.Delay(howLong);
                resultsTextBox.Text += 
                    "\r\n    Task.Delay is finished--returning from called method.";
            }
        }
    
        // Output with Call #1 or Call #2. (Wait for the last line to appear.)
    
        // Entering the Click event handler.
        //   Entering calling method.
        //     Entering called method, starting and awaiting Task.Delay.
        //   Returning from calling method.
        // Exiting the Click event handler.
        //     Task.Delay is finished--returning from called method.
    
    
        // Output with Call #3, which awaits the call to CalledMethodAsync.
    
        // Entering the Click event handler.
        //   Entering calling method.
        //     Entering called method, starting and awaiting Task.Delay.
        //     Task.Delay is finished--returning from called method.
        //   Returning from calling method.
        // Exiting the Click event handler.
    }
    
  5. Choisissez la touche F5 pour exécuter le programme, puis choisissez le bouton Démarrer .

    La sortie appropriée apparaît à la fin de le code.

Voir aussi

Référence

await (Référence C#)

Concepts

Programmation asynchrone avec Async et Await (C# et Visual Basic)