C# 锁块内部的异常

C# 锁块内部的异常,c#,.net,exception,locking,C#,.net,Exception,Locking,比方说,如果我在C代码上有以下代码块: 公共类同步类 { 公共void addData(对象v) { 锁定(锁定对象) { //我可以担心这里会有例外吗? //做这项工作 //arr.Add(v); } } 私有列表arr=新列表(); 私有对象lockObject=新对象(); } 我是否应尝试捕获锁块内的异常?(我主要担心的是锁内可能会引发异常,这将阻止锁被“解锁”。当异常从锁块逃逸时,锁将被释放 这是因为编译器将lock(){…}大致翻译为: Monitor.Enter(obj); tr

比方说,如果我在C代码上有以下代码块:

公共类同步类
{
公共void addData(对象v)
{
锁定(锁定对象)
{
//我可以担心这里会有例外吗?
//做这项工作
//arr.Add(v);
}
}
私有列表arr=新列表();
私有对象lockObject=新对象();
}

我是否应尝试捕获
块内的异常?(我主要担心的是锁内可能会引发异常,这将阻止锁被“解锁”。

当异常从锁块逃逸时,锁将被释放

这是因为编译器将
lock(){…}
大致翻译为:

Monitor.Enter(obj);
try{

 // contents of the lock block

}finally{
    Monitor.Exit(obj);
}

形式为“lock(x)…”的lock语句,其中x是引用类型的表达式,与(C#4.0)完全等效:


<> P>除了释放互斥体之外,还有更多的考虑。

锁发生异常将释放锁,但程序现在处于什么状态?等待锁的线程现在将被唤醒,并且可能正在处理无效状态。这是一个没有理想解决方案的难题

最好的办法是尽量保持锁尽可能小,并调用不会抛出错误的方法。(这忽略了房间中的元素,它是邪恶的
ThreadAbortException
。)


有关这些问题的详细讨论,请参阅Eric Lippert的文章:。

如果最终在调用堆栈的某个位置发现异常,那么它应该是正常的。否则你的应用程序就会崩溃:)是的,说起来容易做起来难。我认为没有一个.NET方法不会引发某种异常。
Monitor.Enter(obj);
try{

 // contents of the lock block

}finally{
    Monitor.Exit(obj);
}
 bool entered = false;
 try { 
    System.Threading.Monitor.Enter(x, ref entered);
  ... 
 }
 finally { if (entered) System.Threading.Monitor.Exit(x); }