Condividi tramite


Because this call is not awaited, the current method continues to run before the call is completed

Error Message

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'Await' operator to the result of the call.

The current method calls an async method that returns a Task or a Task<TResult> and doesn’t apply the Await operator to the result. The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected. Usually other aspects of the calling method depend on the results of the call or, minimally, the called method is expected to complete before you return from the method that contains the call.

An equally important issue is what happens with exceptions that are raised in the called async method. An exception that’s raised in a method that returns a Task or Task<TResult> is stored in the returned task. If you don't await the task or explicitly check for exceptions, the exception is lost. If you await the task, its exception is rethrown.

As a best practice, you should always await the call.

By default, this message is a warning. For more information about hiding warnings or treating warnings as errors, see Configuring Warnings in Visual Basic.

Error ID: BC42358

To address this warning

  • You should consider suppressing the warning only if you're sure that you don't want to wait for the asynchronous call to complete and that the called method won't raise any exceptions. In that case, you can suppress the warning by assigning the task result of the call to a variable.

    The following example shows how to cause the warning, how to suppress it, and how to await the call.

        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
    

    In the example, if you choose Call #1 or Call #2, the unawaited async method (CalledMethodAsync) finishes after both its caller (CallingMethodAsync) and the caller's caller (StartButton_Click) are complete. The last line in the following output shows you when the called method finishes. Entry to and exit from the event handler that calls CallingMethodAsync in the full example are marked in the 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.
    

Example

The following Windows Presentation Foundation (WPF) application contains the methods from the previous example. The following steps set up the application.

  1. Create a WPF application, and name it AsyncWarning.

  2. In the Visual Studio Code Editor, choose the MainWindow.xaml tab.

    If the tab isn't visible, open the shortcut menu for MainWindow.xaml in Solution Explorer, and then choose View Code.

  3. Replace the code in the XAML view of MainWindow.xaml with the following code.

    <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>
    

    A simple window that contains a button and a text box appears in the Design view of MainWindow.xaml.

    For more information about the XAML Designer, see Creating a UI by using XAML Designer. For information about how to build your own simple UI, see the "To create a WPF application" and "To design a simple WPF MainWindow" sections of Walkthrough: Accessing the Web by Using Async and Await (C# and Visual Basic).

  4. Replace the code in MainWindow.xaml.vb with the following code.

    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. Choose the F5 key to run the program, and then choose the Start button.

    The expected output appears at the end of the code.

See Also

Reference

Await Operator (Visual Basic)

Concepts

Asynchronous Programming with Async and Await (C# and Visual Basic)