13

たとえば、C# コードに次のブロックがあるとします。

public class SynchedClass
{
    public void addData(object v)
    {
        lock(lockObject)
        {
            //Shall I worry about catching an exception here?

            //Do the work
            //arr.Add(v);
        }
    }
    private List<object> arr = new List<object>();
    private object lockObject = new object();
}

lockブロック内で例外をキャッチしようとしますか? (私の主な懸念は、ロックの「ロック解除」を妨げる例外がロック内で発生する可能性があることです。)

4

3 に答える 3

28

例外がロック ブロックから抜け出すと、ロックが解放されます。

これはlock(){...}、コンパイラによって大まかに次のように変換されるためです。

Monitor.Enter(obj);
try{

 // contents of the lock block

}finally{
    Monitor.Exit(obj);
}
于 2013-04-07T09:05:59.650 に答える
3

ミューテックスを解放するだけでなく、考慮すべきことがあります。

内で例外が発生するlockとロックが解除されますが、プログラムは現在どのような状態になっているのでしょうか? ロックを待機しているスレッドが起動し、無効な状態を処理する可能性があります。これは、理想的な解決策がない難しい問題です。

最善の方法は、ロックをできるだけ小さく保ち、スローしないメソッドを呼び出すことです。(それは悪である部屋の象を無視していThreadAbortExceptionます...)

これらの問題について詳しくは、Eric Lippert の記事: Locks and exceptions do not mix を参照してください。

于 2013-04-07T09:32:30.763 に答える
2

"lock (x) ..." という形式のロック ステートメント (x は参照型の式) は、(C# 4.0) とまったく同じです。

 bool entered = false;
 try { 
    System.Threading.Monitor.Enter(x, ref entered);
  ... 
 }
 finally { if (entered) System.Threading.Monitor.Exit(x); }
于 2013-04-07T09:07:17.600 に答える