Sdílet prostřednictvím


Upozornění kompilátoru (úroveň 1) CS4014

Protože toto volání není očekáváno, vykonávání aktuální metody pokračuje před dokončením volání.Zvažte použití operátoru await na výsledek volání.

Aktuální metoda vyvolá asynchronní metodu, která vrací Task nebo Task<TResult> a se nevztahuje vyčkání operátor na výsledek.Volání asynchronní metody začne asynchronní úlohy.Nicméně protože žádný await je použit operátor, bude program pokračovat bez čekání na dokončení úlohy.Ve většině případů není toto chování, můžete očekávat.Obvykle další aspekty volající metody závisí na výsledcích volání nebo minimální, očekává dokončení před návratu z metody, která obsahuje volání volané metody.

Stejně důležité je, co se stane s výjimky, které jsou vyvolány v asynchronní volané metody.Výjimku, která je vyvolána v metodě, která vrací Task nebo Task<TResult> je uložen ve vrácených úkolů.Pokud vyčkání úkolu nebo explicitně kontrolovat výjimek, výjimky ztracena.Pokud vyčkání úkol, je jeho výjimka vyvolány.

Jako nejlepší praxe by měla vždy očekávat volání.

Měli byste zvážit, potlačení upozornění, pouze v případě, že jste si jisti, že nechcete čekat na dokončení asynchronní volání a volané metody nedojde k vyvolání výjimky.V takovém případě lze potlačit upozornění přiřazením úkolů výsledek volání proměnné.

Následující příklad ukazuje, jak vyvolat upozornění, jak ji potlačit a jak vyčkání volání.

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

V příkladu, pokud se rozhodnete, #1 nebo #2, unawaited asynchronní metody (CalledMethodAsync) končí po obou jeho volající (CallingMethodAsync) a volající volajícího (startButton_Click) byly dokončeny.Poslední řádek následující výstup ukazuje, po dokončení volané metody.Vstupu a výstupu z obslužné rutiny události, která volá CallingMethodAsync v plné příkladu jsou označeny ve výstupu.

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.

Může také potlačit upozornění kompilátoru pomocí # pragma upozornění (C#-Reference) směrnic.

Příklad

Následující aplikace Windows Presentation Foundation (WPF) obsahuje metody z předchozího příkladu.Následující kroky umožňují nastavit aplikaci.

  1. Vytvoření aplikace WPF a pojmenujte jej AsyncWarning.

  2. V editoru Visual Studio kód, zvolte MainWindow.xaml kartu.

    Pokud na kartě není zobrazen, otevřete místní nabídku pro MainWindow.xaml v Průzkumníkua pak zvolte Zobrazit kód.

  3. Nahraďte kód ve XAML zobrazení MainWindow.xaml následujícím kódem.

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

    Jednoduché okno, které obsahuje tlačítko a textové pole se zobrazí v Návrh zobrazení MainWindow.xaml.

    Další informace o nástroji Designer jazyka XAML, viz Creating a UI by using XAML Designer.Informace o tom, jak vytvořit jednoduché rozhraní naleznete v tématu "Vytvoření aplikace WPF" a "design jednoduchý MainWindow WPF" části Názorný postup: Přístup K webu pomocí asynchronní a vyčkání (C# a Visual Basic).

  4. Kód v MainWindow.xaml.cs nahraďte následující kód.

    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. Zvolte klávesu F5, chcete-li spustit program a pak zvolte Start tlačítko.

    Očekávaný výstup se zobrazí na konci kódu.

Viz také

Referenční dokumentace

vyčkání (C#-Reference)

Koncepty

Asynchronní asynchronní pro programování a očekávat (C# a Visual Basic)