由于此调用未等待,因此在调用完成之前,当前方法的执行将继续执行。 请考虑将 Await 运算符应用于调用的结果。
当前方法调用一个异步方法,该方法返回或返回Task<TResult>一个Task,并且不对结果应用 Await 运算符。 对异步方法的调用将启动异步任务。 但是,由于未 Await 应用任何运算符,程序将继续运行,而无需等待任务完成。 在大多数情况下,不需要该行为。 调用方法的其他方面通常取决于调用的结果,或者,在从包含调用的方法返回之前,调用方法应完成。
同样重要的问题是,在调用异步方法中引发异常时会发生什么情况。 在返回TaskTask<TResult>或存储在返回的任务的方法中引发的异常。 如果不等待任务或显式检查异常,异常将丢失。 如果等待任务,则会重新引发其异常。
最佳做法是,应始终等待呼叫。
默认情况下,此消息是警告。 有关隐藏警告或将警告视为错误的详细信息,请参阅 在 Visual Basic 中配置警告。
错误 ID: BC42358
解决此警告
仅当确定不想等待异步调用完成并且调用方法不会引发任何异常时,才应考虑取消警告。 在这种情况下,可以通过向变量分配调用的任务结果来禁止显示警告。
以下示例演示如何引发警告、如何取消警告以及如何等待调用:
Async Function CallingMethodAsync() As Task
ResultsTextBox.Text &= vbCrLf & " 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.
Dim 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 the warning.
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, the 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. The 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 &= vbCrLf & " Returning from calling method."
End Function
Async Function CalledMethodAsync(howLong As Integer) As Task
ResultsTextBox.Text &= vbCrLf & " Entering called method, starting and awaiting Task.Delay."
' Slow the process down a little so you can distinguish between awaiting
' and not awaiting. Adjust the value for howLong if necessary.
Await Task.Delay(howLong)
ResultsTextBox.Text &= vbCrLf & " Task.Delay is finished--returning from called method."
End Function
在此示例中,如果选择“调用”#1 或“调用”#2,则取消唤醒的异步方法()在调用方(CalledMethodAsyncCallingMethodAsync)和调用方(StartButton_Click)完成后完成。 以下输出中的最后一行显示调用方法完成的时间。 在输出中标记完整示例中调用 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.
示例:
以下 Windows Presentation Foundation (WPF) 应用程序包含上一个示例中的方法。 以下步骤设置应用程序:
创建 WPF 应用程序并将其命名
AsyncWarning。在 Visual Studio Code 编辑器中,选择 MainWindow.xaml 选项卡。
如果选项卡不可见,请在 解决方案资源管理器中打开 MainWindow.xaml 的快捷菜单,然后选择“ 查看代码”。
将 MainWindow.xaml 的 XAML 视图中的代码替换为以下代码:
<Window x:Class="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>包含按钮和文本框的简单窗口显示在 MainWindow.xaml 的设计 视图中。
有关 XAML 设计器的详细信息,请参阅 使用 XAML 设计器创建 UI。 有关如何生成自己的简单 UI 的信息,请参阅演练的“创建 WPF 应用程序”和“设计简单的 WPF MainWindow”部分 :使用 Async 和 Await 访问 Web。
将MainWindow.xaml.vb中的代码替换为以下代码。
Class MainWindow Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs) ResultsTextBox.Text &= vbCrLf & "Entering the Click event handler." Await CallingMethodAsync() ResultsTextBox.Text &= vbCrLf & "Exiting the Click event handler." End Sub Async Function CallingMethodAsync() As Task ResultsTextBox.Text &= vbCrLf & " 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. Dim 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 the warning. 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, the 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. The 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 &= vbCrLf & " Returning from calling method." End Function Async Function CalledMethodAsync(howLong As Integer) As Task ResultsTextBox.Text &= vbCrLf & " Entering called method, starting and awaiting Task.Delay." ' Slow the process down a little so you can distinguish between awaiting ' and not awaiting. Adjust the value for howLong if necessary. Await Task.Delay(howLong) ResultsTextBox.Text &= vbCrLf & " Task.Delay is finished--returning from called method." End Function End Class ' 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. ' Output ' 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 键,然后选择 “开始 ”按钮。
预期输出显示在代码末尾。