Compilerwarnung (Stufe 1) CS4014Compiler Warning (level 1) CS4014

Da auf diesen Aufruf nicht gewartet wird, wird die Ausführung der aktuellen Methode vor Abschluss des Aufrufs fortgesetzt.Because this call is not awaited, execution of the current method continues before the call is completed. Ziehen Sie ein Anwenden des „Await“-Operators auf das Ergebnis des Aufrufs in Betracht.Consider applying the 'await' operator to the result of the call.

Die aktuelle Methode ruft eine asynchrone Methode auf, die Task oder Task<TResult> zurückgibt und nicht den await-Operator auf das Ergebnis anwendet.The current method calls an async method that returns a Task or a Task<TResult> and doesn’t apply the await operator to the result. Der Aufruf der asynchronen Methode startet eine asynchrone Aufgabe.The call to the async method starts an asynchronous task. Da jedoch kein await-Operator angewendet wird, wird das Programm fortgesetzt, ohne auf den Abschluss der Aufgabe zu warten.However, because no await operator is applied, the program continues without waiting for the task to complete. Dieses Verhalten wird in den meisten Fällen nicht erwartet.In most cases, that behavior isn't what you expect. Andere Aspekte der aufrufenden Methode hängen in der Regel von den Ergebnissen des Aufrufs ab, mindestens jedoch wird erwartet, dass die aufgerufene Methode abgeschlossen wird, bevor Sie von der Methode zurückgegeben, die den Aufruf enthält.Usually other aspects of the calling method depend on the results of the call or, minimally, the called method is expected to complete before you return from the method that contains the call.

Ein gleichermaßen wichtiges Problem besteht in der Behandlung von Ausnahmen, die in der aufgerufenen asynchrone Methode ausgelöst werden.An equally important issue is what happens to exceptions that are raised in the called async method. Eine Ausnahme, die in einer Methode ausgelöst wird, die Task oder Task<TResult> zurückgibt, wird in der zurückgegebenen Aufgabe gespeichert.An exception that's raised in a method that returns a Task or Task<TResult> is stored in the returned task. Wenn Sie nicht auf die Aufgabe warten oder explizit auf Ausnahmen hin prüfen, geht die Ausnahme verloren.If you don't await the task or explicitly check for exceptions, the exception is lost. Wenn Sie auf die Aufgabe warten, wird die Ausnahme erneut ausgelöst.If you await the task, its exception is rethrown.

Als bewährte Methode sollten Sie immer auf den Aufruf warten.As a best practice, you should always await the call.

Ziehen Sie eine Unterdrückung der Warnung nur dann in Betracht, wenn Sie sicher sind, dass Sie nicht auf den Abschluss des asynchronen Aufrufs warten möchten und dass die aufgerufene Methode keine Ausnahmen auslösen wird.You should consider suppressing the warning only if you're sure that you don't want to wait for the asynchronous call to complete and that the called method won't raise any exceptions. In diesem Fall können Sie die Warnung unterdrücken, indem Sie das Aufgabenergebnis des Aufrufs einer Variablen zuweisen.In that case, you can suppress the warning by assigning the task result of the call to a variable.

Das folgende Beispiel zeigt, wie Sie die Warnung auslösen und unterdrücken können und wie Sie auf den Aufruf warten können.The following example shows how to cause the warning, how to suppress it, and how to await the call.

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

Wenn Sie beispielsweise „Call #1“ oder „Call #2“ wählen, wird die unerwartete asynchrone Methode (CalledMethodAsync) beendet, nachdem der Aufrufer (CallingMethodAsync) und der Aufrufer des Aufrufers (startButton_Click) abgeschlossen sind.In the example, if you choose Call #1 or Call #2, the unawaited async method (CalledMethodAsync) finishes after both its caller (CallingMethodAsync) and the caller's caller (startButton_Click) are complete. Die letzte Zeile in der folgenden Ausgabe zeigt, wann die aufgerufene Methode beendet ist.The last line in the following output shows you when the called method finishes. Der Eingang und das Ende des Ereignishandlers, der CallingMethodAsync im vollständigen Beispiel aufruft, werden in der Ausgabe gekennzeichnet.Entry to and exit from the event handler that calls CallingMethodAsync in the full example are marked in the output.

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 Compiler-Warnungen mithilfe der #pragma-Warnungsdirektive unterdrücken.You can also suppress compiler warnings by using #pragma warning directives.

BeispielExample

Die folgende Windows Presentation Foundation (WPF)-Anwendung enthält die Methoden aus dem vorherigen Beispiel.The following Windows Presentation Foundation (WPF) application contains the methods from the previous example. Die folgenden Schritte richten die Anwendung ein.The following steps set up the application.

  1. Erstellen Sie eine WPF-Anwendung, und geben Sie Ihr den Namen AsyncWarning.Create a WPF application, and name it AsyncWarning.

  2. Wählen Sie im Visual Studio Code Editor die Registerkarte MainWindow.xaml aus.In the Visual Studio Code Editor, choose the MainWindow.xaml tab.

    Wenn die Registerkarte nicht sichtbar ist, öffnen Sie das Kontextmenü für „MainWindow.xaml“ im Projektmappen-Explorer, und wählen Sie dann Code anzeigenaus.If the tab isn't visible, open the shortcut menu for MainWindow.xaml in Solution Explorer, and then choose View Code.

  3. Ersetzen Sie den Code in der XAML -Ansicht der MainWindow.xaml-Datei durch den folgenden Code.Replace the code in the XAML view of MainWindow.xaml with the following code.

    <Window x:Class="AsyncWarning.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="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 Entwurf -Ansicht der MainWindow.xaml-Datei angezeigt.A simple window that contains a button and a text box appears in the Design view of MainWindow.xaml.

    Weitere Informationen zum XAML-Designer finden Sie unter Erstellen einer Benutzeroberfläche mit dem XAML-Designer.For more information about the XAML Designer, see Creating a UI by using XAML Designer. Informationen zum Erstellen der eigenen einfachen Benutzeroberfläche finden Sie in den Abschnitten „So erstellen Sie eine WPF-Anwendung“ und „So entwerfen Sie ein einfaches WPF-MainWindow“ auf der Seite Exemplarische Vorgehensweise: Zugreifen auf das Web mit Async und Await.For information about how to build your own simple UI, see the "To create a WPF application" and "To design a simple WPF MainWindow" sections of Walkthrough: Accessing the Web by Using Async and Await.

  4. Ersetzen Sie den Code in „MainWindow.xaml.cs“ durch den folgenden Code.Replace the code in MainWindow.xaml.cs with the following 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 .Choose the F5 key to run the program, and then choose the Start button.

    Am Ende des Codes wird die erwartete Ausgabe angezeigt.The expected output appears at the end of the code.

Siehe auchSee Also

awaitawait
Asynchrone Programmierung mit Async und AwaitAsynchronous Programming with async and await