8

MSDN ドキュメントおよびクラスの使用例の多くでReaderWriterLockSlimは、次のパターンの使用が推奨されています。

cacheLock.EnterWriteLock();
try
{
    //Do something
}
finally
{
    cacheLock.ExitWriteLock();
}

しかし、それが完全に安全かどうかは気になります。ロックが取得された後、tryステートメントの前に何らかの例外が発生して、ロックがロックされた状態でスタックする可能性はありますか? 最も明白な候補はThreadAbortExceptionです。この状況の可能性は非常に小さいことは理解していますが、結果は非常に悪いので、検討する価値があると思います. tryコンパイラがこのパターンを理解し、プロセッサがステートメントの前にスレッドを中断するのを防いでいるとは思えません。

このコードが安全ではないという理論的な可能性がある場合、より安全にする方法はありますか?

4

2 に答える 2

8

これが理論的に失敗する可能性のある方法は、私が考えることができる 3 つのみです。

  • ThreadAbortExceptionあなたはすでに述べました。これを正しく処理するのはかなり簡単ですThread.Abort()。ほとんどの場合、その必要はありません。ほとんどの場合、目的の結果を達成するためのより良い方法があります。

    本当に、本当に、本当にそれを呼び出す必要があり、中止しようしているスレッドがロックを開いたままにするリスクがある場合にのみ、コードのブロック全体 ( from Enterto Exit) をtry...finally句に配置します。 try ブロックは空です。現在のハンドラーが終了したときThread.Abort()にのみスローされます。ThreadAbortExceptionfinally

  • StackOverflowException別の可能性です。への呼び出し中に発生する可能性がありますExitWriteLock。これもかなり簡単です。スタック オーバーフローが発生すると、プロセスが終了します。これをキャッチまたは処理することはできません。プロセスが終了するため、プロセス内の他のスレッドがロックを開いたままにすることはありません。

  • OutOfMemoryExceptionへの呼び出し中に理論的にスローされる可能性がありますExitWriteLock。とは異なりStackOverflowException、これは理論的にはキャッチ可能です。キャッチしないと、プロセスは終了し、プロセス内の他のスレッドはロックを開いたままにしません。ただし、これをキャッチした場合、これを正しく処理することは期待できず、他のスレッドもすぐにこの例外をスローし始める可能性があります。

要するに、私はそれについて心配する必要はありません。

于 2014-07-02T14:15:29.420 に答える