ホームページ >バックエンド開発 >C++ >C# の `lock` ステートメント内で `await` が禁止されているのはなぜですか?

C# の `lock` ステートメント内で `await` が禁止されているのはなぜですか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2025-01-15 06:43:44394ブラウズ

Why is `await` Prohibited Inside a `lock` Statement in C#?

制限の理解: C# の awaitlock

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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。