制限の理解: C# の await
と lock
C# の await
キーワードは非同期プログラミングにとって重要であり、ノンブロッキング操作を可能にします。 ただし、await
ステートメント内で lock
を使用することは固く禁止されています。この制限は、一般的なエラーの原因であるデッドロックを防ぐための重要な設計上の選択です。
Microsoft のドキュメントでは、await
内の lock
式がリスクを引き起こすと説明しています。 await
が制御を譲った後にコードの実行が一時停止され、後で別のスレッドで再開される可能性があります。このタイミングのギャップにより、他のスレッドがロックを取得し、ロックの順序が逆転してデッドロックが発生する状況が発生する可能性があります。
仮説的な例を見てみましょう:
<code class="language-csharp">class Async { public static async Task<IDisposable> Lock(object obj) { while (!Monitor.TryEnter(obj)) await Task.Yield(); return new ExitDisposable(obj); } private class ExitDisposable : IDisposable { private readonly object obj; public ExitDisposable(object obj) { this.obj = obj; } public void Dispose() { Monitor.Exit(this.obj); } } }</code>
このコードは非同期ロックを模倣しようとしていますが、コンパイラーが示すように、ExitDisposable.Dispose()
内で無期限にブロックされる傾向があり、デッドロックが発生する可能性があります。 これは、Monitor.Exit
がロックを取得したスレッドとは異なるスレッドで実行され、ロック順序に違反する可能性があるために発生します。
本質的に、await
内での lock
の禁止は、マルチスレッド アプリケーションでのデッドロックを回避するための事前の対策です。 非同期操作と lock
ステートメントの組み合わせを避け、リーダー/ライター ロックや System.Threading
.
以上がC# の `lock` ステートメント内で `await` が禁止されているのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。