最近、C# でのロックの実装に関する Eric Lippert の投稿を読みましたが、まだいくつかの疑問が残っています。
4.0 の実装では、finally ブロックの Monitor.Exit(temp) が実行される直前にスレッド アボートまたはクロス スレッド例外が発生した場合、オブジェクトのロックは保持されますか?
このレベルで例外が発生し、オブジェクトがロックされたままになる可能性はありますか?
最近、C# でのロックの実装に関する Eric Lippert の投稿を読みましたが、まだいくつかの疑問が残っています。
4.0 の実装では、finally ブロックの Monitor.Exit(temp) が実行される直前にスレッド アボートまたはクロス スレッド例外が発生した場合、オブジェクトのロックは保持されますか?
このレベルで例外が発生し、オブジェクトがロックされたままになる可能性はありますか?
Monitor.Exit(temp)
4.0 の実装では、finally ブロックが実行される直前にスレッド アボートまたはクロス スレッド例外が発生した場合、オブジェクトのロックは保持されますか?
他の読者にもわかりやすいように、そのコードを見てみましょう。
bool lockWasTaken = false;
var temp = obj;
try
{
Monitor.Enter(temp, ref lockWasTaken);
{
body
}
}
finally
{
if (lockWasTaken)
{
// What if a thread abort happens right here?
Monitor.Exit(temp);
}
}
あなたの質問は、false の仮定に基づいているため、答えられません。つまり、最終ブロックの途中でスレッドの中止が発生する可能性があります。
スレッドの中止は、finally ブロックの途中で発生することはありません。これは、スレッドをアボートしてはならない多くの理由の 1 つにすぎません。スレッド全体が finally ブロックで実行されている可能性があるため、中止できません。
このレベルで例外が発生し、オブジェクトがロックされたままになる可能性はありますか?
いいえ。スレッドの中止は、制御が最終的に離れるまで延期されます。有効なロックを解除しても、メモリが割り当てられたり、別の例外がスローされたりすることはありません。