BC42358:由于此调用未等待,因此在调用完成之前,当前方法的执行将继续执行

由于此调用未等待,因此在调用完成之前,当前方法的执行将继续执行。 请考虑将 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) 应用程序包含上一个示例中的方法。 以下步骤设置应用程序:

  1. 创建 WPF 应用程序并将其命名 AsyncWarning

  2. 在 Visual Studio Code 编辑器中,选择 MainWindow.xaml 选项卡。

    如果选项卡不可见,请在 解决方案资源管理器中打开 MainWindow.xaml 的快捷菜单,然后选择“ 查看代码”。

  3. 将 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

  4. 将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.
    
  5. 选择要运行程序的 F5 键,然后选择 “开始 ”按钮。

    预期输出显示在代码末尾。

另请参阅