컴파일러 경고(수준 1) CS4014
이 호출이 대기되지 않으므로 호출이 완료되기 전에 현재 메서드가 계속 실행됩니다.호출 결과에 'await' 연산자를 적용해 보십시오.
현재 메서드가 반환 하는 비동기 메서드 호출을 Task 또는 Task<TResult> 및 적용 되지 않습니다는 기다립니다 연산자는 결과.비동기 메서드를 호출 하는 비동기 작업을 시작합니다.그러나 있기 때문에 없음 await 연산자 적용 프로그램 작업이 완료 되기를 기다리지 않고 계속 됩니다.대부분의 경우 예상 대로 동작 하지 않습니다.일반적으로 다른 측면을 호출 하는 메서드 호출의 결과에 따라 달라 집니다. 또는 적어도 호출된 된 메서드 호출을 포함 하는 메서드를 반환 하기 전에 완료 예정입니다.
동등 하 게 중요 한 문제는 어떻게 호출된 비동기 메서드에서 발생 하는 예외입니다.반환 하는 메서드를 발생 시킨 예외는 Task 또는 Task<TResult> 에서 반환 된 작업을 저장 합니다.에 대 한 예외를 명시적으로 확인 하거나 작업을 기다립니다 하지 않으면 예외가 손실 됩니다.작업을 기다립니다 경우 해당 예외가 다시 throw 됩니다.
가장 좋은 방법은 항상 호출을 기다립니다 해야 합니다.
비동기 호출이 완료 될 때까지 기다립니다 않으려는 및 호출된 된 메서드가 예외를 발생 되지 않습니다 확실 경우 경고를 억제 하는 것이 좋습니다.이 경우 호출 하 여 변수에 작업 결과 할당 하 여 경고를 억제할 수 있습니다.
다음 예제에서는 경고가 발생 하는 방법을 억제 하는 방법 및 호출을 기다립니다 하는 방법을 보여 줍니다.
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.";
}
예제 호출 #1 또는 #2, unawaited async 메서드를 호출 하면 (CalledMethodAsync) 완료 후 모두 호출자 (CallingMethodAsync) 및 호출자의 호출자 (startButton_Click) 완료 됩니다.다음 출력에서 마지막 줄에 호출된 된 메서드를 완료 하면 표시 됩니다.항목 및 exit를 호출 하는 이벤트 처리기에서 CallingMethodAsync 에서 전체 예제 출력에 표시 됩니다.
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.
사용 하 여 컴파일러 경고를 억제할 수 있습니다 #pragma warning(C# 참조) 지시문입니다.
예제
다음 Windows Presentation Foundation (WPF) 응용 프로그램에서는 이전 예제의 메서드를 포함합니다.다음 단계는 응용 프로그램을 설정합니다.
WPF 응용 프로그램을 만들고 이름을 AsyncWarning.
Visual Studio 코드 편집기에서 선택 된 MainWindow.xaml 탭.
탭이 표시 되지 않으면 Mainwindow.xaml에 대 한 바로 가기 메뉴 열기 솔루션 탐색기, 다음을 선택 하 고 코드 보기.
코드를 대체는 XAML Mainwindow.xaml의 다음 코드 보기.
<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>
단추 및 텍스트 상자에 포함 된 간단한 창이 표시는 디자인 Mainwindow.xaml의 보기.
XAML 디자이너에 대 한 자세한 내용은 XAML 디자이너를 사용하여 UI 만들기.간단한 UI를 빌드하는 방법에 대 한 내용은 "WPF 응용 프로그램 만들기" 및 "간단한 WPF MainWindow 디자인" 섹션의 연습: Async 및 Await를 사용하여 웹에 액세스(C# 및 Visual Basic).
Mainwindow.xaml.cs의 코드를 다음 코드로 대체 합니다.
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. }
프로그램을 실행 한 다음 선택 합니다 F5 키를 선택 하 여 시작 단추.
예상된 출력 코드의 끝에 나타납니다.