由于不等待此调用,因此在调用完成之前,当前方法将继续运行

错误消息

由于此调用不会等待,因此在调用完成前将继续执行当前方法。应用调用的结果的考虑“Await运算符。

当前方法调用返回 TaskTask<TResult>,不应用 等待 运算符应用于该结果的异步方法。对异步方法的调用将启动异步任务。但是,在中,因为 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,在其调用方(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)应用程序包含前面示例中的方法。以下步骤将的应用程序。

  1. 创建一个WPF应用程序,并将其命名为 AsyncWarning。

  2. 在Visual Studio代码编辑器"中,选择 *** MainWindow.xaml *** 选项。

    如果看不到选项卡,打开MainWindow.xaml的快捷菜单在 *** 解决方案资源管理器 ***,然后选择 *** 查看代码 ***

  3. 用下面的代码替换在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的”部分。

  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键运行程序,然后选择 *** 启动 *** 按钮。

    预期的输出显示在代码的结尾。

请参见

参考

Await 运算符 (Visual Basic)

概念

使用 Async 和 Await 的异步编程(C# 和 Visual Basic)