由于不等待此调用,因此在调用完成之前,当前方法将继续运行
错误消息
由于此调用不会等待,因此在调用完成前将继续执行当前方法。应用调用的结果的考虑“Await运算符。
当前方法调用返回 Task 或 Task<TResult>,不应用 等待 运算符应用于该结果的异步方法。对异步方法的调用将启动异步任务。但是,在中,因为 Await 运算符不是应用的,程序将继续运行,而不等待任务完成。在大多数情况下,此行为不需要。通常被调用的方法的其他方面依赖于调用的结果,或者最低限度上,调用方法预计完成,在从包含调用的方法之前返回。
同样重要的问题是发生在调用异步方法引发的异常。在方法引发返回 Task 或 Task<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,在其调用方(CallingMethodAsync)之后的unawaited异步方法(CalledMethodAsync)完成,并且调用方的调用方(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代码编辑器"中,选择 *** MainWindow.xaml *** 选项。
如果看不到选项卡,打开MainWindow.xaml的快捷菜单在 *** 解决方案资源管理器 ***,然后选择 *** 查看代码 ***。
用下面的代码替换在MainWindow.xaml *** XAML *** 视图中的代码。
<Window x:Class="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的信息,请参见 演练:使用 Async 和 Await 访问 Web(C# 和 Visual Basic)“创建WPF应用程序”和“设计简单的WPF的”部分。
用下面的代码替换在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键运行程序,然后选择 *** 启动 *** 按钮。
预期的输出显示在代码的结尾。