锁定块内的异常

时间:2013-04-07 09:05:19

标签: c# .net exception locking

说,如果我在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块内的异常吗? (我主要担心的是,锁内部可能会引发异常,这会阻止锁被“解锁”。)

3 个答案:

答案 0 :(得分:21)

当异常从锁定块中逃脱时,将释放锁定。

这是因为lock(){...}大致由编译器翻译成:

Monitor.Enter(obj);
try{

 // contents of the lock block

}finally{
    Monitor.Exit(obj);
}

答案 1 :(得分: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); }

答案 2 :(得分:2)

除了发布互斥锁之外,还有更多要考虑的因素。

使用lock发生的异常将释放锁定,但现在该程序处于什么状态?等待锁的线程现在将被唤醒,现在可能正在处理无效状态。这是一个难以解决的问题。

最好的办法是尽量让你的锁尽可能小,并调用不抛出的方法。 (这忽略了房间里的elepant是邪恶的ThreadAbortException ...)

有关这些问题的详细讨论,请参阅Eric Lippert的文章:Locks and exceptions do not mix