简体   繁体   English

锁定块内的异常

[英]Exceptions inside the lock block

Say, if I have the following block on C# code: 比方说,如果我在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();
}

Shall I attempt to catch exceptions inside the lock block? 我应该尝试捕获lock块内的异常吗? (My main concern is that the exception may be raised inside the lock which will prevent the lock from being "unlocked".) (我主要担心的是锁内部可能会引发异常,这会阻止锁被“解锁”。)

Lock will be released when exception escapes from the lock block. 当异常从锁定块中逃逸时,将释放锁定。

That is because lock(){...} is translate by compiler roughly into: 这是因为lock(){...}被编译器大致翻译成:

Monitor.Enter(obj);
try{

 // contents of the lock block

}finally{
    Monitor.Exit(obj);
}

There is more to consider than just releasing the mutex. 除了发布互斥锁之外,还有更多考虑因素。

An exception occuring withing a lock will release the lock, but what state is the program in now? 使用lock发生的异常将释放锁定,但现在该程序处于什么状态? A thread waiting on the lock will now wake up, and will perhaps now be dealing with invalid state. 等待锁的线程现在将被唤醒,现在可能正在处理无效状态。 This is a difficult problem with no ideal solution. 这是一个难以解决的问题。

The best thing is to try to keep your locks as small as possible and to call methods that don't throw. 最好的办法是尽量保持你的锁定,并调用不抛出的方法。 (That's ignoring the elepant in the room that is the evil ThreadAbortException ...) (这忽略了房间中的elepant是邪恶的ThreadAbortException ......)

For a good discussion of these issues, see Eric Lippert's article: Locks and exceptions do not mix . 有关这些问题的详细讨论,请参阅Eric Lippert的文章: 锁定和异常不会混合

A lock statement of the form "lock (x) ..." where x is an expression of a reference-type, is precisely equivalent to (C# 4.0): 形式为“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); }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM