CA2007:タスクを直接待機しないでください

プロパティ
ルール ID CA2007
Title タスクを直接待機しないでください
[カテゴリ] 信頼性
修正が中断ありか中断なしか なし
.NET 8 では既定で有効 いいえ

原因

非同期メソッドでは Task を直接待機します。

規則の説明

非同期メソッドで Task を直接待機すると、非同期コンテキストによっては、タスクを作成したのと同じスレッドで継続が発生します。 この動作はパフォーマンスの面で大きな負担が生じ、その結果 UI スレッドでデッドロックが発生する可能性があります。 Task.ConfigureAwait(Boolean) を呼び出して継続の意図を示すことを検討してください。

違反の修正方法

違反を修正するには、待機した TaskConfigureAwait を呼び出します。 continueOnCapturedContext パラメーターには、true または false のいずれかを渡すことができます。

  • タスクで ConfigureAwait(true) を呼び出すと、明示的に ConfigureAwait を呼び出さない場合と同じ動作が行われます。 このメソッドを明示的に呼び出すことにより、元の同期コンテキストで継続を意図的に実行することをリーダーに通知できます。

  • タスクで ConfigureAwait(false) を呼び出して、継続をスレッド プールにスケジュールします。これにより、UI スレッドでデッドロックが発生するのを回避できます。 false を渡すことは、アプリに依存しないライブラリに適したオプションです。

次のコード スニペットでは、警告が表示されます。

public async Task Execute()
{
    Task task = null;
    await task;
}

違反を修正するには、待機している TaskConfigureAwait を呼び出します。

public async Task Execute()
{
    Task task = null;
    await task.ConfigureAwait(false);
}

どのようなときに警告を抑制するか

この警告は、任意の環境でコードを実行するライブラリ、および環境、メソッドの呼び出し元が呼び出す方法、または待機方法についてコードが想定しないライブラリを対象としています。 通常、ライブラリ コードではなく、アプリケーション コードを表すプロジェクトでは、警告を完全に抑制するのが妥当です。実際、このアナライザーをアプリケーション コードで実行すると (たとえば、WinForms または WPF プロジェクトのボタン クリック イベント ハンドラー)、間違ったアクションが実行される可能性があります。

継続を元のコンテキストに戻すようにスケジュールするか、またはそのようなコンテキストが適切な場所にない場合に、この警告を抑制できます。 たとえば、WinForms または WPF アプリケーションのボタン クリック イベント ハンドラーでコードを記述する場合、通常、待機からの継続は UI スレッドで実行する必要があるため、継続を元のコンテキストに戻す既定の動作が望ましいです。 別の例として、ASP.NET Core アプリケーションでコードを記述する場合、既定では SynchronizationContext または TaskScheduler がありません。そのため、ConfigureAwait は実際には動作を変更しません。

警告を抑制する

単一の違反を抑制するだけの場合は、ソース ファイルにプリプロセッサ ディレクティブを追加して無効にしてから、規則をもう一度有効にします。

#pragma warning disable CA2007
// The code that's violating the rule is on this line.
#pragma warning restore CA2007

ファイル、フォルダー、またはプロジェクトの規則を無効にするには、構成ファイルでその重要度を none に設定します。

[*.{cs,vb}]
dotnet_diagnostic.CA2007.severity = none

詳細については、「コード分析の警告を抑制する方法」を参照してください。

分析するコードを構成する

次のオプションを使用して、コードベースのどの部分に対してこのルールを実行するかを構成します。

これらすべてのオプションを構成できる対象は、この規則だけ、それを適用するすべての規則、それを適用するこのカテゴリ (信頼性) のすべての規則のいずれかです。 詳細については、「コード品質規則の構成オプション」を参照してください。

非同期の void メソッドを除外する

値を返さない非同期メソッドをこの規則から除外するかどうかを構成できます。 これらの種類のメソッドを除外するには、プロジェクトの .editorconfig ファイルに次のキーと値のペアを追加します。

# Package version 2.9.0 and later
dotnet_code_quality.CA2007.exclude_async_void_methods = true

# Package version 2.6.3 and earlier
dotnet_code_quality.CA2007.skip_async_void_methods = true

出力の種類

また、この規則を適用する出力アセンブリの種類を構成することもできます。 たとえば、コンソール アプリケーションまたは動的にリンクされるライブラリ (つまり、UI アプリではない) を生成するコードにのみこの規則を適用するには、プロジェクトの .editorconfig ファイルに次のキーと値のペアを追加します。

dotnet_code_quality.CA2007.output_kind = ConsoleApplication, DynamicallyLinkedLibrary

関連項目