次の方法で共有


await 演算子を使用して非同期メソッドのエラーと警告を解決する

この記事では、次のコンパイラ エラーについて説明します。

  • CS1983: これは非同期メソッドであるため、戻り値の式は 'Task<T>' ではなく 'T' 型である必要があります。
  • CS1985: catch 句で await 式を使用できません。
  • CS1986: 'await' では、型に適切な 'GetAwaiter' メソッドが必要です。
  • CS1989: 非同期ラムダ式を式ツリーに変換することはできません。
  • CS1991: 'Type' は Windows ランタイム イベントであり、'event' は通常の .NET イベントであるため、'event' を実装できません。
  • CS1992: 'await' 演算子は、'async' 修飾子でマークされたメソッドまたはラムダ式内に含まれている場合にのみ使用できます。
  • CS1994: 'async' 修飾子は、本体を持つメソッドでのみ使用できます。
  • CS1995: 'await' 演算子は、最初の 'from' 句の最初のコレクション式内、または 'join' 句のコレクション式内でのみ使用できます。
  • CS1996: lock ステートメント内で待機できません。
  • CS1997: 関数は値を返す非同期メソッドであるため、return キーワードの後にオブジェクト式を続けてはなりません。
  • CS1998: この非同期メソッドには 'await' 演算子がないため、同期的に実行されます。'await' 演算子を使用して非ブロッキング API 呼び出しを待機するか、'await Task.Run(...)' を使用してバックグラウンド スレッドで CPU バインド処理を実行することを検討してください。
  • CS4008: 'void' を待機できません。
  • CS4009: void または int 戻り値のエントリ ポイントを非同期にすることはできません。
  • CS4014: この呼び出しは待機されていないため、現在のメソッドの実行は呼び出しが完了する前に続行されます。呼び出しの結果に await 演算子を適用することを検討してください。
  • CS4032: 'await' 演算子は、非同期メソッド内でのみ使用できます。このメソッドを 'async' 修飾子でマークし、その戻り値の型を 'Task<T>' に変更することを検討してください。
  • CS4033: 'await' 演算子は、非同期メソッド内でのみ使用できます。このメソッドを 'async' 修飾子でマークし、戻り値の型を 'Task' に変更することを検討してください。
  • CS8892: 同期エントリ ポイントが見つかったため、メソッドはエントリ ポイントとして使用されません。
  • CS9123: '&' 演算子は、非同期メソッドのパラメーターまたはローカル変数では使用しないでください。
  • CS9330: 'MethodImplAttribute.Async' をメソッドに手動で適用することはできません。メソッドに 'async' をマークします。

Await 式の要件

  • CS1985: catch 節では await を使用できません。
  • CS1986: 'await' では、型に適切な 'GetAwaiter' メソッドが必要です。
  • CS1992: 'await' 演算子は、'async' 修飾子でマークされたメソッドまたはラムダ式内に含まれている場合にのみ使用できます。
  • CS1995: 'await' 演算子は、最初の 'from' 句の最初のコレクション式内、または 'join' 句のコレクション式内でのみ使用できます。
  • CS1996: lock ステートメントの本体で await を使用できません。
  • CS4008: 'void' を待機できません。
  • CS4032: 'await' 演算子は、非同期メソッド内でのみ使用できます。このメソッドを 'async' 修飾子でマークし、その戻り値の型を 'Task<T>' に変更することを検討してください。
  • CS4033: 'await' 演算子は、非同期メソッド内でのみ使用できます。このメソッドを 'async' 修飾子でマークし、その戻り値の型を 'Task' に変更することを検討してください。

await演算子を正しく使用するには、次の規則に従います。 詳細については、「 async および await を使用した非同期プログラミング」を参照してください。

  • catch 句 (await) ではを使用しないでください。 try ブロックと finally ブロック (C# 6 以降) で await を使用できますが、catch ブロックは例外処理と制御フローで特別な課題を提示します。
  • awaitlockステートメントブロック (CS1996) 内で使用しないでください。 コンパイラでは、デッドロックが発生しやすいコードの生成を回避するために、これをサポートしていません。
  • awaitクエリ式 (CS1995) 内の特定の場所、つまり最初のfrom句のコレクション式内、またはjoin句のコレクション式内でのみ使用します。
  • async修飾子でメソッドまたはラムダ式をマークしてからawait (CS1992、CS4032、CS4033) を使用します。
  • 待機中の型に、awaiter 型 (GetAwaiter) を返すアクセス可能な メソッドがあることを確認します。
  • await型 (void) の式にはを適用しないでください。
  • 戻り値を返さないメソッドの場合は Task に戻り、値を返すメソッドの場合は Task<T> に戻り値の型を変更します。

非同期メソッドシグネチャの要件

  • CS1983: これは非同期メソッドであるため、戻り値の式は 'Task<T>' ではなく 'T' 型である必要があります。
  • CS1994: 'async' 修飾子は、本体を持つメソッドでのみ使用できます。
  • CS4009: void または int 戻り値のエントリ ポイントを非同期にすることはできません。
  • CS8892: 同期エントリ ポイントが見つかったため、メソッドはエントリ ポイントとして使用されません。
  • CS9330: 'MethodImplAttribute.Async' をメソッドに手動で適用することはできません。メソッド 'async' をマークします。

非同期メソッドを正しく宣言するには、次のシグネチャ要件に従います。 詳細については、「 非同期メイン戻り値」を参照してください。

  • 有効な型 ( voidTaskTask<T>、タスクに似た型、 IAsyncEnumerable<T>、または IAsyncEnumerator<T> (CS1983) のいずれかを返します。
  • async修飾子は、本体を持つメソッドでのみ使用します (CS1994)。 インターフェイスまたはクラスの抽象メソッドの async 修飾子を削除します。
  • async エントリ ポイントでMainを使用するように C# 7.1 以降に更新するか、以前のバージョン (async) のエントリ ポイントでを使用しないようにします。
  • 同期エントリ ポイントと非同期エントリ ポイントの両方がある場合は、同期エントリ ポイントを削除します (CS8892)。
  • asyncを手動で適用する代わりに、MethodImplAttribute.Async キーワードを使用します (CS9330)。

非同期のプラクティス

  • CS1989: 非同期ラムダ式を式ツリーに変換することはできません。
  • CS1991: 'Type' は Windows ランタイム イベントであり、'event' は通常の .NET イベントであるため、'event' を実装できません。
  • CS1997: 関数は値を返す非同期メソッドであるため、return キーワードの後にオブジェクト式を続けてはなりません。
  • CS1998: この非同期メソッドには 'await' 演算子がないため、同期的に実行されます。'await' 演算子を使用して非ブロッキング API 呼び出しを待機するか、'await Task.Run(...)' を使用してバックグラウンド スレッドで CPU バインド処理を実行することを検討してください。
  • CS4014: この呼び出しは待機されていないため、現在のメソッドの実行は呼び出しが完了する前に続行されます。呼び出しの結果に await 演算子を適用することを検討してください。
  • CS9123: '&' 演算子は、非同期メソッドのパラメーターまたはローカル変数では使用しないでください。

非同期コードを正しく記述し、一般的な落とし穴を回避するには、次のベスト プラクティスに従います。 詳細については、「 async および await を使用した非同期プログラミング」を参照してください。

  • またはTask (Task<TResult>) を返す非同期メソッドの呼び出しを常に待機します。 待機していない呼び出しは、例外が失われたり予期しない動作を引き起こしたりする可能性があります。
  • Task (非ジェネリック) を返す非同期メソッドから値を返さないでください。代わりに Task<T> を使用します (CS1997)。
  • 非同期メソッドに少なくとも 1 つの await 演算子を含めるか、 async 修飾子 (CS1998) を削除します。
  • メソッドがreturnを返す必要がある場合は、Task ステートメントを削除します (CS1997CS1998)。
  • メソッドの戻り値の型を Task<T> に変更して値を返します (CS1997CS1998)。
  • 非同期ステート マシン (async) が不要な場合は、修飾子を削除し、タスク直接返します。
  • 式ツリー (CS1989) では非同期メソッドを使用しないでください。 式ツリーはコードをデータとして表し、非同期メソッドに必要な複雑なステート マシン変換をサポートしていません。
  • インターフェイスまたは WinRT イベントのアクセサーを非同期 (CS1991) としてマークしないでください。 これは、Windows ランタイムの相互運用性に関するプラットフォーム固有の制限です。
  • 非同期メソッド (&) 内の式で address-of 演算子 () を使用しないでください。 中断中にターゲットがメモリ内に再配置され、ポインターが無効になる可能性があります。