次の方法で共有


BC42358: この呼び出しは待機されていないため、現在のメソッドの実行は呼び出しが完了する前に続行されます

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

現在のメソッドは、 Task または Task<TResult> を返し、 Await 演算子を結果に適用しない非同期メソッドを呼び出します。 非同期メソッドの呼び出しにより、非同期タスクが開始されます。 ただし、 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) と呼び出し元の呼び出し元 (StartButton_Click) の両方が完了した後に、未承認の非同期メソッド (CalledMethodAsync) が完了します。 次の出力の最後の行は、呼び出されたメソッドが終了したときに表示されます。 完全な例で 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 を構築する方法については、「 チュートリアル: Async と Await を使用して Web にアクセスする」の「WPF アプリケーションを作成するには」および「単純な WPF MainWindow を設計するには」セクションを参照してください。

  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 キーを押してプログラムを実行し、[ スタート ] ボタンを選択します。

    予想される出力がコードの末尾に表示されます。

こちらも参照ください