Avertissement du compilateur (niveau 1) CS4014

Cet appel n’étant 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.

La méthode actuelle appelle une méthode asynchrone qui retourne Task ou Task<TResult> et n’applique pas l’opérateur await au résultat. L'appel à la méthode asynchrone lance une tâche asynchrone. Toutefois, étant donné qu'aucun opérateur await n'est appliqué, le programme se poursuit sans attendre la tâche à exécuter. Dans la plupart des cas, ce comportement n'est pas ce que vous attendez. En général, les autres aspects de la méthode d'appel dépendent des résultats de l'appel ou, au moins, la méthode appelée est censée se terminer avant le retour de la méthode qui contient l'appel.

Une question tout aussi importante n'est autre que de savoir ce que deviennent les exceptions générées dans la méthode asynchrone appelée. Une exception générée dans une méthode qui renvoie Task ou Task<TResult> est stockée dans la tâche renvoyée. Si vous n'attendez pas la tâche ou si vous vérifiez explicitement les exceptions, l'exception est perdue. Si vous attendez la tâche, l'exception est renvoyée.

À titre de recommandation, vous devriez toujours attendre l'appel.

Envisagez de supprimer l'avertissement uniquement si vous êtes certain que vous ne souhaitez pas attendre l'exécution de l'appel asynchrone et que la méthode appelée ne génèrera pas d'exception. Dans ce cas, vous pouvez supprimer l'avertissement en affectant le résultat de la tâche à une variable.

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

static async Task CallingMethodAsync(int millisecondsDelay)
{
    Console.WriteLine("  Entering calling method.");

    // 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(millisecondsDelay);

    // 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(millisecondsDelay);

    // 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(millisecondsDelay);

    Console.WriteLine("  Returning from calling method.");
}

static async Task CalledMethodAsync(int millisecondsDelay)
{
    Console.WriteLine("    Entering called method, starting and awaiting Task.Delay.");

    await Task.Delay(millisecondsDelay);

    Console.WriteLine("    Task.Delay is finished--returning from called method.");
}

Dans cet exemple, si vous choisissez Call #1 ou Call #2, la méthode asynchrone non attendue CalledMethodAsync se termine une fois que son appelant CallingMethodAsync et l'appelant de l'appelant se sont terminés. La dernière ligne de la sortie suivante vous indique lorsque 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 à l’aide des directives #pragma warning.

Exemple

L’application console suivante contient les méthodes issues de l’exemple précédent. Les étapes suivantes permettent d'installer l'application.

  1. Créez une application console et nommez-la AsyncWarning.

  2. Dans l’éditeur Visual Studio Code, choisissez le fichier Program.cs.

  3. Remplacez le code dans Program.cs par le code suivant.

    using System;
    using System.Threading.Tasks;
    
    namespace AsyncWarning
    {
        class Program
        {
            static async Task Main()
            {
                Console.WriteLine("Entering Main() application entry point.");
    
                int millisecondsDelay = 2000;
                await CallingMethodAsync(millisecondsDelay);
    
                Console.WriteLine("Exiting Main() application entry point.");
    
                await Task.Delay(millisecondsDelay + 500);
            }
    
            static async Task CallingMethodAsync(int millisecondsDelay)
            {
                Console.WriteLine("  Entering calling method.");
    
                // 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(millisecondsDelay);
    
                // 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(millisecondsDelay);
    
                // 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(millisecondsDelay);
    
                Console.WriteLine("  Returning from calling method.");
            }
    
            static async Task CalledMethodAsync(int millisecondsDelay)
            {
                Console.WriteLine("    Entering called method, starting and awaiting Task.Delay.");
    
                await Task.Delay(millisecondsDelay);
    
                Console.WriteLine("    Task.Delay is finished--returning from called method.");
            }
        }
    
        // Output with Call #1 or Call #2. (Wait for the last line to appear.)
    
        // Entering Main() application entry point.
        //   Entering calling method.
        //     Entering called method, starting and awaiting Task.Delay.
        //   Returning from calling method.
        // Exiting Main() application entry point.
        //     Task.Delay is finished--returning from called method.
    
        // Output with Call #3, which awaits the call to CalledMethodAsync.
    
        // Entering Main() application entry point.
        //   Entering calling method.
        //     Entering called method, starting and awaiting Task.Delay.
        //     Task.Delay is finished--returning from called method.
        //   Returning from calling method.
        // Exiting Main() application entry point.
    }
    
  4. Sélectionnez la touche F5 pour exécuter le programme.

La sortie attendue apparaît à la fin du code.

Voir aussi