この記事では、次のコンパイラ エラーについて説明します。
-
CS1983: これは非同期メソッドであるため、戻り値の式は '
T' ではなく 'Task<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 バインド処理を実行することを検討してください。 - CS4001: 式を待つことができません。
-
CS4003: '
await' は、非同期メソッドまたはラムダ式内の識別子として使用できません。 - CS4005: 非同期メソッドはポインター型パラメーターを持つことができません。
- CS4006: 非同期メソッドのパラメーター リストでは、__arglistは許可されません。
-
CS4007: 型のインスタンスは、'
await' または 'yield' 境界を越えて保持できません。 -
CS4008: '
void' を待機できません。 - CS4009: void または int 戻り値のエントリ ポイントを非同期にすることはできません。
- CS4010: 非同期式をデリゲート型に変換できません。非同期式は void、Task、または Task<T> を返しますが、いずれも型に変換できない場合があります。
-
CS4011: '
await' には、'{1}' の戻り値の型が必要です。GetAwaiter()' には、適切な 'IsCompleted'、'OnCompleted'、および 'GetResult' メンバーがあり、'INotifyCompletion' または 'ICriticalNotifyCompletion' を実装します。 - CS4012: 型のパラメーターは、非同期メソッドまたは非同期ラムダ式では宣言できません。
-
CS4014: この呼び出しは待機されていないため、現在のメソッドの実行は呼び出しが完了する前に続行されます。呼び出しの結果に
await演算子を適用することを検討してください。 - CS4015: 'MethodImplOptions.Synchronized' を非同期メソッドに適用できません。
- CS4016: これは非同期メソッドであるため、戻り値の式は、宣言された型ではなく型のような型タスクである必要があります。
- CS4027: 式の型は、必要なメンバーを実装していません。
-
CS4028: '
await' は、型が適切な 'GetAwaiter' メソッドを持っていることを必要とします。'System' の using ディレクティブを忘れていませんか? - CS4029: 'void' 型の式を返すことはできません。
- CS4030: セキュリティ属性を Async メソッドに適用できません。
- CS4031: 'SecurityCritical' 属性または 'SecuritySafeCritical' 属性を持つインターフェイス、クラス、または構造体では、非同期メソッドを使用できません。
-
CS4032: '
await' 演算子は、非同期メソッド内でのみ使用できます。このメソッドを 'async' 修飾子でマークし、その戻り値の型を 'Task<T>' に変更することを検討してください。 -
CS4033: '
await' 演算子は、非同期メソッド内でのみ使用できます。このメソッドを 'async' 修飾子でマークし、戻り値の型を 'Task' に変更することを検討してください。 -
CS4034: '
await' 演算子は、非同期メソッド内でのみ使用できます。このメソッドを 'async' 修飾子でマークすることを検討してください。 - CS8031: デリゲートを返すタスクに変換された非同期ラムダ式は、値を返すことができません。
-
CS8100: '
await' 演算子は、静的スクリプト変数初期化子では使用できません。 - CS8177: 非同期メソッドに参照ローカルを含めることはできません。
-
CS8178: メソッドの呼び出しによって返される参照は、'
await' または 'yield' 境界を越えて保持できません。 - CS8204: 型ターゲットの AsyncMethodBuilder として使用する型の場合、その Task プロパティは、宣言された型ではなくターゲット型を返す必要があります。
-
CS8403: IAsyncEnumerable
asyncT< を返すには、反復子ブロックを持つメソッドを '>' にする必要があります。 - CS8411: 型に必要なメンバーに適したパブリック インスタンスまたは拡張定義が含まれていないため、非同期 foreach ステートメントは型の変数を操作できません。
- CS8892: 同期エントリ ポイントが見つかったため、メソッドはエントリ ポイントとして使用されません。
- CS8935: AsyncMethodBuilder 属性は、明示的な戻り値の型を持たない匿名メソッドでは許可されません。
- CS8940: 一般的なタスクに似た戻り値の型が必要でしたが、'AsyncMethodBuilder' 属性で見つかった型は適していません。これはアリティ 1 の非連結ジェネリック型である必要があり、その包含型 (存在する場合) は非ジェネリックである必要があります。
-
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' に変更することを検討してください。 -
CS4034: '
await' 演算子は、非同期メソッド内でのみ使用できます。このメソッドを 'async' 修飾子でマークすることを検討してください。 -
CS8178: この呼び出しによって返される参照は、'
await' または 'yield' 境界を越えて保持できません。 - CS8411: 型に必要なメンバーに適したパブリック インスタンスまたは拡張定義が含まれていないため、非同期 foreach ステートメントは型の変数を操作できません。
- CS4001: 式を待機できません。
-
CS4003: '
await' は、非同期メソッドまたはラムダ式内の識別子として使用できません。 -
CS4007: 型のインスタンスは、'
await' または 'yield' 境界を越えて保持できません。 -
CS4011: '
await' では、'GetAwaiter()' の戻り値の型が適切な 'IsCompleted'、'OnCompleted'、および 'GetResult' メンバーを持ち、'INotifyCompletion' または 'ICriticalNotifyCompletion' を実装する必要があります。 - CS4027: 型に必要なメンバーが実装されていません。
-
CS4028: '
await' には、型に適切な 'GetAwaiter' メソッドが必要です。もしかして 'System' の using ディレクティブが足りないのではありませんか? -
CS8100: '
await' 演算子は、静的スクリプト変数初期化子では使用できません。
次の項目では、各エラーを修正する方法について説明します。
await演算子と awaiter パターンの詳細については、「async および await を使用した非同期プログラミング」を参照してください。
-
async修飾子を、await式 (CS1992、CS4032、CS4033、CS4034) を含むメソッドまたはラムダ式に追加します。 コンパイラでは、非同期の中断と再開を処理するステート マシンを生成できるように、async修飾子が必要です。 このエラーの 3 つのバリアントは、正しい戻り値の型のコンテキスト固有の提案を提供します。 - C# 5 以前 (
await) をターゲットとする場合、catch式を ブロックから移動します。 C# 6 以降では、コンパイラはawaitブロックとcatchブロックの両方でfinallyをサポートしています。 このエラーは、C# 6 以降では生成されなくなりました。 - ステートメント ブロックの外に
await式を移動しますlock(CS1996)。 ロックを保持している間に非同期処理が中断されると、デッドロックのリスクがあります。 ロックはスレッド スイッチ間で保持され、他のコードが同じロックを待機している可能性があります。 - クエリ式を再構築し、 が最初の
awaitまたはfrom(join) のコレクション式にのみ表示されるようにします。 他のクエリ句は、非同期中断をサポートしていないラムダ式に変換されます。 - 待機中の式の型を、アクセス可能な
GetAwaiter()メソッドを公開し、awaiter パターン (CS1986, CS4028) に従うように変更します。 この型は、直接または拡張メソッドを使用してパターンを実装できます。GetAwaiterメソッドが存在するが、usingのSystemディレクティブがない場合、コンパイラは CS1986 ではなくより具体的な CS4028 メッセージを生成します。 -
GetAwaiter()によって返される awaiter 型がIsCompleted、OnCompleted、およびGetResultメンバーを持ち、INotifyCompletionまたはICriticalNotifyCompletion (CS4011、CS4027) を実装していることを確認します。await式は、完了状態の確認、継続の登録、結果の取得を行うために、これらのメンバーに依存します。 - 呼び出されたメソッドの戻り値の型を
voidから Task または Task<TResult> に変更して、結果を待機できるようにします (CS4008)。 完了を追跡したり例外を伝達したりするタスク オブジェクトがないため、void返すメソッドを待機できません。 -
awaited 式を awaiter パターン (CS4001) をサポートする型に変更します。
int、string、その他の組み込み型などの型にはGetAwaiterメソッドがないため、直接待機することはできません。 -
(
await) を使用する前に、ref を返すメソッド呼び出しの結果をローカル変数に格納します。 非同期ステート マシンが別のスレッドまたはコンテキストで中断および再開され、参照が無効になる可能性があるため、メソッドによって返された参照をawait境界を越えて保持することはできません。 - コレクション型にIAsyncEnumerable<T>を実装するか、
GetAsyncEnumeratorメンバーとCurrentメンバーを持つ型を返すアクセス可能なMoveNextAsyncメソッドを追加します (CS8411)。await foreachステートメントでは、コレクション型が非同期列挙可能パターンに従う必要があります。 -
awaitメソッドまたはラムダ式 (async) 内の という名前のローカル変数またはパラメーターの名前を変更します。 非同期コンテキスト内では、awaitはコンテキスト キーワードであり、識別子として使用することはできません。 -
await式を静的スクリプト変数初期化子からメソッド本体 (CS8100) に移動します。 静的初期化子は非同期コンテキストの外部で実行されるため、awaitはその場所では使用できません。 -
ref structインスタンスをawaitまたはyield境界 (CS4007) を越えて保持する必要がないようにコードを再構築します。 非同期ステート マシンはヒープにローカル変数を格納し、ref struct型は設計上スタック バインドされます。中断ポイント間でヒープ ストレージに安全に移動することはできません。
非同期メソッドシグネチャの要件
-
CS1983: これは非同期メソッドであるため、戻り値の式は '
Task<T>' ではなく 'T' 型である必要があります。 -
CS1994: '
async' 修飾子は、本体を持つメソッドでのみ使用できます。 - CS4009: void または int 戻り値のエントリ ポイントを非同期にすることはできません。
- CS8892: 同期エントリ ポイントが見つかったため、メソッドはエントリ ポイントとして使用されません。
- CS8935: AsyncMethodBuilder 属性は、明示的な戻り値の型を持たない匿名メソッドでは許可されません。
- CS8940: 一般的なタスクに似た戻り値の型が必要でしたが、'AsyncMethodBuilder' 属性で見つかった型は適していません。これはアリティ 1 の非連結ジェネリック型である必要があり、その包含型 (存在する場合) は非ジェネリックである必要があります。
-
CS8403: 反復子ブロックを持つメソッドは、'
async' を返すために '{1}' である必要があります。 -
CS9330: '
MethodImplAttribute.Async' をメソッドに手動で適用することはできません。メソッド 'async' をマークします。 - CS4005: 非同期メソッドはポインター型パラメーターを持つことができません。
- CS4006: __arglistは、非同期メソッドのパラメーター リストでは使用できません。
- CS4010: 非同期ラムダをデリゲート型に変換できません。非同期ラムダは void、Task、または Task<T> を返しますが、いずれも戻り値の型に変換できない可能性があります。
- CS4012: 型のパラメーターは、非同期メソッドまたは非同期ラムダ式では宣言できません。
- CS4015: 'MethodImplOptions.Synchronized' を非同期メソッドに適用できません。
- CS4016: これは非同期メソッドであるため、戻り値の式は型ではなくタスク型である必要があります。
- CS8031: デリゲートを返すタスクに変換された非同期ラムダ式は、値を返すことができません。
- CS8204: 型の AsyncMethodBuilder として使用する型の場合、その Task プロパティは、宣言された型ではなく必須の型を返す必要があります。
次の項目では、各エラーを修正する方法について説明します。 非同期メソッド宣言の詳細については、 async 修飾子と 非同期の戻り値の型を参照してください。
- 非同期メソッドの基になる結果の型 (CS1983、CS4016) と一致するように戻り式 を変更します。 非同期メソッドが
Task<T>を返す場合、returnステートメントは、TではなくTask<T>型の値を指定する必要があります。これは、コンパイラによって生成されたステート マシンがタスク内の値を自動的にラップするためです。 CS1983 は、メソッドがTask<T>を返し、式がTされたときに表示されます。 CS4016 では、 戻り値の式の型が一致しない一般的なケースについて説明します。 - 抽象メソッドやインターフェイス メソッド宣言 (
async) などの本体を持たないメソッドから、修飾子を削除します。 コンパイラがステート マシンの実装を生成できるように、async修飾子にはメソッド本体が必要です。 - 非同期エントリ ポイントの戻り値の型を Task または Task<TResult> (CS4009) に変更します。 C# 7.1 以降では、
Mainメソッド をasyncできますが、TaskまたはTask<int>-async voidを返す必要があり、async intは有効なエントリ ポイントシグネチャではありません。 - プロジェクトに同期メソッドと非同期
Mainメソッド (CS8892) の両方が含まれている場合は、1 つのエントリ ポイントを削除または名前変更します。 コンパイラは同期エントリ ポイントを選択し、無視する非同期候補に対してこの警告を発行します。 -
[AsyncMethodBuilder]属性 (CS8935) を適用する前に、ラムダ式に明示的な戻り値の型を追加します。 コンパイラは、属性がコンパイル時に特定の戻り値の型と一致する必要があるため、戻り値の型が推論される匿名メソッドのビルダー型を解決できません。 -
[AsyncMethodBuilder]属性で指定された型を、MyTaskMethodBuilder<>ではなくMyTaskMethodBuilder<T>や非ジェネリック型 (CS8940) の代わりに、引数個数が1の非境界ジェネリック型に変更します。 ビルダーの包含型 (存在する場合) もジェネリックでない必要があります。 コンパイラでは、具体的なタスクに似た戻り値の型に対してビルダーを構築できるように、この図形が必要です。 - manual
[MethodImpl(MethodImplOptions.Async)]属性を、メソッド宣言のasyncキーワード (CS9330) に置き換えます。MethodImplOptions.Asyncフラグは内部ランタイム用に予約されており、ユーザー コードで直接適用することはできません。 -
asyncを含み、またはIAsyncEnumerable<T>を返すメソッドにIAsyncEnumerator<T>修飾子を追加します (CS8403)。async修飾子がないと、コンパイラはメソッドを同期反復子として扱い、非同期ストリームステート マシンを生成できません。 - 非同期メソッド (CS4005) からポインター型パラメーターを削除します。 ポインターは、非同期中断ポイント間で安全に保持できない固定メモリの場所を参照します。この場所では、別のスレッドで実行が再開される可能性があります。
- 非同期メソッドパラメーター リスト (
__arglist) からを削除します。 可変長引数リストは、ヒープ割り当て 非同期ステート マシンと互換性のないスタック ベースの呼び出し規則に依存します。 - 非同期メソッドまたは非同期ラムダ式 (
ref) から、in、out、またはref structパラメーター、およびSpan<T>やReadOnlySpan<T>などの型のパラメーターを削除します。 これらのパラメーター型はスタック バインドであり、ヒープ割り当て非同期ステート マシンクロージャでは安全にキャプチャできません。 - 非同期ラムダの戻り値の型 (CS4010) に一致するようにターゲット デリゲート型を変更します。 非同期ラムダは、
void、 Task、または Task<TResult>を返すことができます。コンパイラは、異なる戻り値の型を必要とする任意のデリゲート型に変換することはできません。 - 非ジェネリック
return返すデリゲートに割り当てられている非同期ラムダからTask式を削除するか、ラムダが値を返すことができるようにデリゲート型をFunc<Task<T>>に変更します (CS8031)。 非ジェネリックTask戻りデリゲートは、結果のない非同期操作を表すので、値を返すと型が一致しません。 - 非同期メソッド (
[MethodImpl(MethodImplOptions.Synchronized)]) から属性を削除します。Synchronizedオプションはメソッド実行全体のロックを取得しますが、非同期メソッドは中断され、異なるスレッドで再開される可能性があり、ロック セマンティクスが未定義になります。 - カスタム
AsyncMethodBuilder型を修正し、そのTaskプロパティが非同期メソッドの宣言された戻り値の型 (CS8204) と同じ型を返すようにします。 コンパイラはビルダーのTaskプロパティを使用して最終的なタスク オブジェクトを取得するため、型の不一致によってステート マシンが正しく機能しなくなります。
非同期のプラクティス
- CS1989: 非同期ラムダ式を式ツリーに変換することはできません。
- CS1991: 'Type' は Windows ランタイム イベントであり、'event' は通常の .NET イベントであるため、'event' を実装できません。
- CS1997: 関数は値を返す非同期メソッドであるため、return キーワードの後にオブジェクト式を続けてはなりません。
-
CS1998: この非同期メソッドには '
await' 演算子がないため、同期的に実行されます。'await' 演算子を使用して非ブロッキング API 呼び出しを待機するか、'await Task.Run(...)' を使用してバックグラウンド スレッドで CPU バインド処理を実行することを検討してください。 -
CS4014: この呼び出しは待機されていないため、現在のメソッドの実行は呼び出しが完了する前に続行されます。呼び出しの結果に
await演算子を適用することを検討してください。 - CS8177: 非同期メソッドに参照ローカルを含めることはできません。
-
CS9123: '
&' 演算子は、非同期メソッドのパラメーターまたはローカル変数では使用しないでください。 - CS4029: 'void' 型の式を返すことはできません。
- CS4030: セキュリティ属性を Async メソッドに適用できません。
- CS4031: 'SecurityCritical' 属性または 'SecuritySafeCritical' 属性を持つインターフェイス、クラス、または構造体では、非同期メソッドを使用できません。
次の項目では、各エラーを修正する方法について説明します。 詳細については、「async および await を使用した非同期プログラミング」および「await演算子」を参照してください。
-
awaitまたはTaskを返すすべての呼び出しにTask<TResult>演算子を追加するか、ファイア アンド フォーゲット動作が本当に意図されている場合は、_ =で結果を明示的に破棄します (CS4014)。awaitしないと、非同期操作によってスローされた例外は自動的に失われ、呼び出し元のメソッドは操作が終了する前に実行が続行され、微妙な順序付けと正確性のバグが発生する可能性があります。 - 戻り値の型が
return(非ジェネリック) の非同期メソッドからTask式を削除するか、メソッドが値を返す必要があるときに戻り値の型をTask<T>に変更します (CS1997)。Taskを返す非同期メソッドでは、コンパイラによってタスク ラッパーが生成されます。値を返すと、メソッド シグネチャが結果を約束しないため、型が一致しません。 - メソッド本体に少なくとも 1 つの
await式を追加するか、async修飾子を削除してタスクを直接返します (CS1998)。async式のないawaitメソッドは完全に同期的に実行されるため、不要なステート マシンのオーバーヘッドが増加します。 メソッドが意図的に同期操作をラップする場合、asyncを削除し、タスクを明示的に返すと、そのオーバーヘッドが排除されます。 - ラムダ式を書き直して、
async(CS1989) のようなExpression<Func<...>>型に割り当てられたときにを使用しないようにします。 式ツリーは、コンパイラが分析または変換できるデータ構造としてコードを表しますが、async生成される複雑なステート マシンを式ツリーにキャプチャすることはできません。 - イベントの実装を変更して、インターフェイス宣言と実装クラスの両方が、イベントで Windows ランタイム セマンティクスと通常の .NET セマンティクス (CS1991) のどちらを使用するかについて一致するようにします。 このエラーは、WinRT イベントを通常の .NET イベントとして実装できない、またはその逆の Windows ランタイム相互運用シナリオに適用されます。
- 非同期メソッド (CS9123) 内のパラメーターまたはローカル変数を参照する式から
&() を削除します。 非同期ステート マシンは、中断中にキャプチャされた変数をヒープに再配置する可能性があります。これにより、アドレスを介して取得されたポインターが無効になります。 - 非同期メソッドから参照渡しされたローカル変数を削除するか、
await境界 (CS8177) にまたがらないように確認します。 非同期ステート マシンは、ヒープ割り当てクロージャ内のローカル変数をキャプチャします。スタックの場所への参照を中断ポイント間で安全に保持することはできません。 C# 13 以降では、refローカルは、await境界をまたがらない限り非同期メソッドで許可され、このエラーは生成されません。 -
return返すメソッドの結果を返すvoidステートメントを削除するか、呼び出されたメソッドを変更して値を返します (CS4029)。return SomeVoidMethod();は値として返すことができる型ではないので、voidを使用することはできません。returnキーワードを削除し、スタンドアロン ステートメントとしてメソッドを呼び出すか、呼び出されたメソッドのシグネチャを変更して具象型を返します。 - 非同期メソッド (
[SecurityCritical]) から[SecuritySafeCritical]やなどのセキュリティ属性を削除するか、これらの属性 (async) でマークされた型のメソッドから修飾子を削除します。 コード アクセス セキュリティ注釈は宣言メソッドに適用されますが、コンパイラによって生成された非同期ステート マシンは、これらのセキュリティ注釈を適用できない別のコンテキストで実行されます。
GitHub で Microsoft と共同作業する
このコンテンツのソースは GitHub にあります。そこで、issue や pull request を作成および確認することもできます。 詳細については、共同作成者ガイドを参照してください。
.NET