Delen via


Compilerwaarschuwing (niveau 1) CS4014

Omdat deze aanroep niet wordt gewacht, wordt de uitvoering van de huidige methode voortgezet voordat de aanroep is voltooid. Overweeg de await operator toe te passen op het resultaat van de aanroep.

De huidige methode roept een asynchrone methode aan die een Task of a Task<TResult> retourneert en de wachtoperator niet op het resultaat toepast. De aanroep van de asynchrone methode start een asynchrone taak. Omdat er echter geen await operator wordt toegepast, wordt het programma voortgezet zonder te wachten tot de taak is voltooid. In de meeste gevallen is dat gedrag niet wat u verwacht. Meestal zijn andere aspecten van de aanroepmethode afhankelijk van de resultaten van de aanroep of, minimaal, wordt verwacht dat de aangeroepen methode wordt voltooid voordat u terugkeert van de methode die de aanroep bevat.

Een even belangrijk probleem is wat er gebeurt met uitzonderingen die worden gegenereerd in de zogenaamde asynchrone methode. Een uitzondering die wordt gegenereerd in een methode die een Task of Task<TResult> meer retourneert in de geretourneerde taak. Als u niet op de taak wacht of expliciet op uitzonderingen controleert, gaat de uitzondering verloren. Als u de taak wacht, wordt de uitzondering opnieuw gestart.

Als best practice moet u altijd wachten op het gesprek.

Overweeg de waarschuwing alleen te onderdrukken als u zeker weet dat u niet wilt wachten tot de asynchrone aanroep is voltooid en dat de aangeroepen methode geen uitzonderingen genereert. In dat geval kunt u de waarschuwing onderdrukken door het taakresultaat van de aanroep aan een variabele toe te wijzen.

In het volgende voorbeeld ziet u hoe u de waarschuwing kunt veroorzaken, hoe u deze onderdrukt en hoe u wacht op de oproep.

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.");
}

Als u in het voorbeeld Oproep #1 of Gesprek #2 kiest, wordt de niet-geopende asynchrone methode CalledMethodAsync voltooid nadat zowel de aanroeper CallingMethodAsync als de beller is voltooid. In de laatste regel in de volgende uitvoer ziet u wanneer de aangeroepen methode is voltooid. Vermelding van en uitgang van de gebeurtenis-handler die in het volledige voorbeeld wordt aanroepen CallingMethodAsync , worden gemarkeerd in de uitvoer.

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.

U kunt compilerwaarschuwingen ook onderdrukken met behulp van #pragma waarschuwingsrichtlijnen .

Opmerking

De volgende consoletoepassing bevat de methoden uit het vorige voorbeeld. Met de volgende stappen stelt u de toepassing in.

  1. Maak een consoletoepassing en geef deze AsyncWarningeen naam.

  2. Kies in de Visual Studio Code-editor het Program.cs-bestand .

  3. Vervang de code in Program.cs door de volgende code.

    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. Selecteer de F5-toets om het programma uit te voeren.

De verwachte uitvoer wordt weergegeven aan het einde van de code.

Zie ook