Share via


Compilerwarnung (Stufe 1) CS4014

Da auf diesen Aufruf nicht gewartet wird, wird die Ausführung der aktuellen Methode vor Abschluss des Aufrufs fortgesetzt.Ziehen Sie ein Anwenden des 'Await'-Operators auf das Ergebnis des Aufrufs in Betracht.

Die aktuelle Methode erhält eine asynchrone Methode auf, die Task oder Task zurückgibt und den Operator Sie erwarten nicht zum Ergebnis angewendet wird. Der Aufruf der asynchronen Methode startet eine asynchrone Aufgabe. Da await kein Operator angewendet wird, wird das Programm fortgesetzt, ohne auf die Aufgabe warten abzuschließen. In den meisten Fällen ist dieses Verhalten nicht, was Sie erwarten. Normalerweise sind andere Aspekte des Aufrufs von Methoden von den Ergebnissen des Aufrufs überein, oder minimale wird die aufgerufene Methode erwartet, um nachzuvollziehen, vor Rückgabe der Methode, die den Aufruf enthält.

Ein einheitlich wichtiges Problem ist, was auf Ausnahmen geschieht, die in der aufgerufenen asynchronen Methode ausgelöst werden. Eine Ausnahme, die in einer Methode ausgelöst wird, die Task oder Task zurückgibt, wird in der zurückgegebenen Aufgabe gespeichert. Wenn Sie die Aufgabe oder explizit die Überprüfung für Ausnahmen erwarten, dass die Ausnahme verloren. Wenn Sie die Aufgabe Ihrer Erwartung, wird die Ausnahme erneut ausgelöst.

Als empfohlene Vorgehensweise sollten Sie den Aufruf stets erwarten.

Sie sollten, die Warnung zu unterdrücken sollten nur, wenn Sie sicher sind, dass Sie nicht auf den asynchronen Aufruf warten möchten, und dass die aufgerufene Methode keine Ausnahmen auslöst. In diesem Fall können Sie die Warnung unterdrücken, indem Sie das Aufgabenergebnis des Aufrufs einer Variablen zuweisen.

Das folgende Beispiel zeigt, wie die Warnung verursacht, wie sie unterdrückt und wie der Aufruf erwartet.

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

Klicken Sie z Aufruf Nr. auswählen oder Nr. aufrufen, werden die unawaited asynchronen Ende der Methode (CalledMethodAsync) nach dessen Aufrufer (CallingMethodAsync) und der Aufrufer des Aufrufers (startButton_Click) abgeschlossen. Die letzte Zeile in der folgenden Ausgabe zeigt Ihnen dar, wenn die aufgerufene Methode beendet. Eintrag zu und Beenden des Ereignishandlers, der CallingMethodAsync im vollständigen Beispiel aufgerufen wird, werden in der Ausgabe markiert.

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.

Sie können auch Compilerwarnungen unterdrücken, indem Sie #pragma warning (C#-Referenz)-Direktive verwenden.

Beispiel

Die folgenden Windows Presentation Foundation (WPF) - Anwendung enthält die Methoden aus dem vorherigen Beispiel. Die folgenden Schritte die installierten Anwendung.

  1. Erstellen einer WPF-Anwendung und nennen Sie diese AsyncWarning.

  2. Wählen Sie im Visual Studio Code Editor die Registerkarte MainWindow.xaml aus.

    Wenn die Registerkarte nicht angezeigt wird, öffnen Sie das Kontextmenü für MainWindow.xaml im Projektmappen-Explorer, und wählen Sie dann Code anzeigen aus.

  3. Ersetzen Sie den Code in der Ansicht XAML der Datei MainWindow.xaml durch den folgenden Code.

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

    Ein einfaches Fenster, das eine Schaltfläche und ein Textfeld enthält, wird in der Ansicht Entwurf von " MainWindow.xaml ".

    Weitere Informationen zum den XAML-Designer, finden Sie unter Erstellen einer Benutzeroberfläche mit dem XAML-Designer. Informationen, wie eigene einfache Benutzeroberfläche, finden Sie in ", um eine WPF-Anwendung erstellt" und ", ein einfaches Abschnitte WPF MainWindow entwerfen" von Exemplarische Vorgehensweise: Zugreifen auf das Web mit Async und Await (C# und Visual Basic).

  4. Ersetzen Sie den Code in MainWindow.xaml.cs durch folgenden Code.

    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. Drücken Sie die Taste F5, um das Programm auszuführen, und klicken Sie dann auf die Schaltfläche Starten.

    Die erwartete Ausgabe wird am Ende des Codes.

Siehe auch

Referenz

await (C#-Referenz)

Konzepte

Asynchrone Programmierung mit Async und Await (C# und Visual Basic)