BC42358:この呼び出しは待機されなかったため、現在のメソッドの実行は呼び出しの完了を待たずに続行されます

この呼び出しは待機されなかったため、現在のメソッドの実行は呼び出しの完了を待たずに続行されます。 呼び出しの結果に Await 演算子を適用することを検討してください。

現在のメソッドは Task または Task<TResult> を返す非同期メソッドを呼び出し、Await 演算子を結果に適用しません。 この非同期メソッドの呼び出しは、非同期タスクを開始します。 ただし、 Await 演算子が適用されないため、プログラムはタスクの完了を待たずに処理を続行します。 ほとんどの場合、この動作は想定されていません。 通常は、呼び出し元のメソッドの他の側面が呼び出しの結果に依存します。また、最低でも、呼び出しを含むメソッドから制御が返される前に、呼び出されたメソッドが完了することが想定されます。

同様に、呼び出された非同期メソッドで発生した例外に対する処理も重要です。 Task または Task<TResult> を返すメソッド内で発生した例外は、返されたタスクに格納されます。 このタスクが返されるのを待たない場合や例外を明示的にチェックしない場合、例外は失われます。 このタスクが返されるのを待機する場合は、例外が再スローされます。

ベスト プラクティスとしては、常に呼び出しを待機する必要があります。

既定では、このメッセージは警告です。 警告を非表示にする方法や、警告をエラーとして扱う方法の詳細については、「 Configuring Warnings in 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) アプリケーションには、前の例のメソッドが含まれています。 次のステップで、アプリケーションを設定します。

  1. WPF アプリケーションを作成し、 AsyncWarningという名前を付けます。

  2. Visual Studio コード エディターで、 [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 を構築する方法については、「チュートリアル: Async と Await を使用した Web へのアクセス」の 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 キーを押してプログラムを実行し、 [Start] を複数回クリックします。

    想定される出力がコードの最後に表示されます。

関連項目