この古い質問への回答の中で、例外時にロックを解除することは非常に危険なことであると誰も言及していないことに注意してください。はい、C#のロックステートメントには「最終的に」セマンティクスがあります。コントロールが正常または異常にロックを終了すると、ロックが解除されます。皆さんはこれについて良いことのように話しているのですが、悪いことです!未処理の例外をスローするロックされた領域がある場合の正しい方法は、ロックを解除して続行するのではなく、より多くのユーザーデータを破棄する直前に、問題のあるプロセスを終了することです。
このように見てください。ドアに鍵がかかったバスルームと、外で待っている人々の列があるとします。トイレの爆弾が爆発し、そこにいる人が死亡した。あなたの質問は、「その状況では、次の人がトイレに入ることができるように、ロックが自動的にロック解除されますか?」です。はい、そうなります。 それは良いことではありません。爆弾が爆発し、誰かを殺しました!配管はおそらく破壊されており、家はもはや構造的に健全ではなく、そこに別の爆弾がある可能性があります。正しいことは、全員をできるだけ早く外に出し、家全体を取り壊すことです。
つまり、考えてみてください。別のスレッドで変更せずにデータ構造から読み取るためにコードの領域をロックし、そのデータ構造内の何かが例外をスローした場合、それはデータ構造が原因である可能性が高いです。破損しています。ユーザーデータがめちゃくちゃになりました。破損したデータを保存するため、この時点ではユーザーデータの保存を試みたくありません。プロセスを終了するだけです。
別のスレッドが同時に状態を読み取らずにミューテーションを実行するためにコードの領域をロックし、ミューテーションがスローされた場合、データが以前に破損していなければ、確実に破損します。これはまさに、ロックが保護することになっているシナリオです。これで、その状態の読み取りを待機しているコードは、すぐに破損状態へのアクセスを許可され、おそらくそれ自体がクラッシュします。繰り返しますが、正しいことはプロセスを終了することです。
どのようにスライスしても、ロック内の例外は悪いニュースです。正しい質問は、「例外が発生した場合にロックがクリーンアップされるか」ではありません。正しい質問は、「ロック内で例外が発生しないようにするにはどうすればよいですか。例外がある場合は、ミューテーションが以前の良好な状態にロールバックされるようにプログラムを構成するにはどうすればよいですか?」です。