Aviso do compilador (nível 1) CS4014
Como esta chamada não é aguardada, a execução do método atual continua antes da conclusão da chamada.Considere aplicar o operador 'await' ao resultado da chamada.
O método atual chama um método de async que retorna Task ou Task<TResult> e não aplica o operador de espere o resultado.A chamada para o método de async inicia uma tarefa assíncrono.Entretanto, porque nenhum operador de await é aplicado, o programa continua sem esperar que a tarefa termina.Na maioria dos casos, esse comportamento não é o que você espera.Geralmente outros aspectos do método de chamada dependem dos resultados da chamada ou, mìnima, o método chamada é esperado terminar antes que você retorna o método que contém a chamada.
Um problema também importante é o que acontece às exceções que são geradas no método chamado de async.Uma exceção que é lançada em um método que retorna Task ou Task<TResult> é armazenada na tarefa retornado.Se você não pretende a tarefa ou explicitamente a verificação para exceções, a exceção é perdida.Se você pretende a tarefa, a exceção é rethrown.
Como prática recomendada, você sempre deve esperar a chamada.
Você deve considerar suprimir o aviso somente se tiver certeza que você não deseja aguardar que a chamada assíncrona para concluir e que o método chamado não gerará nenhuma exceções.Nesse caso, você pode suprimir o aviso atribuindo o resultado da tarefa de chamada a uma variável.
O exemplo a seguir mostra como fazer com que o aviso, como suprimi-lo, e como esperar a chamada.
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.";
}
No exemplo, se você escolher a chamada nº ou chama #2, os unawaited conclusão do método de async (CalledMethodAsync) após o chamador (CallingMethodAsync) e o chamador do chamador (startButton_Click) está concluída.A última linha de saída a seguir mostra quando o método chamado completa.Entrada e a saída do manipulador de eventos que chama CallingMethodAsync no exemplo completo são marcadas na saída.
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.
Você também pode eliminar avisos do compilador usando diretivas de Aviso de # pragma (referência de C#) .
Exemplo
O seguinte aplicativo Windows Presentation Foundation (WPF) contém os métodos do exemplo anterior.As seguintes etapas para configurar o aplicativo.
Criar um aplicativo WPF, e denomine-o AsyncWarning.
No editor de códigos do Visual Studio, escolha a guia MainWindow.xaml .
Se a guia não estiver visível, abra o menu de atalho para MainWindow.xaml em Gerenciador de Soluções, e escolha Exibir Código.
Substitua o código no modo de XAML de MainWindow.xaml com o código a seguir.
<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>
Uma janela simples que contém um botão e uma caixa de texto aparece no modo de Design de MainWindow.xaml.
Para obter mais informações sobre o designer de exibição XAML, consulte Criando uma interface de usuário usando o Designer XAML.Para obter informações sobre como criar seu próprio interface de usuário simples, consulte “para criar um aplicativo WPF” e “criar seções WPF um MainWindow simples” de Passo a passo: Acessando a Web usando Async e aguardar (C# e Visual Basic).
Substitua o código em MainWindow.xaml.cs com o código a seguir.
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. }
Escolha a tecla F5 para executar o programa, escolha o botão de Iniciar .
A saída previstas aparecem no final do código.
Consulte também
Referência
Conceitos
Programação com Async assíncrona e esperar (C# e Visual Basic)