由于此调用未等待,因此在调用完成之前,当前方法的执行将继续执行。 请考虑将 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,则取消唤醒的异步方法()在调用方(CalledMethodAsync
CallingMethodAsync
)和调用方(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 键,然后选择 “开始 ”按钮。
预期输出显示在代码末尾。