我最近阅读了 Eric Lippert 关于 c# 中的锁实现的这篇文章,但仍然存在一些问题。
在 4.0 实现中,如果在 finally 块中的 Monitor.Exit(temp) 执行之前发生线程中止或任何跨线程异常 - 那会保持对象上的锁定吗?
在这个级别是否有可能发生异常,使对象仍处于锁定状态?
我最近阅读了 Eric Lippert 关于 c# 中的锁实现的这篇文章,但仍然存在一些问题。
在 4.0 实现中,如果在 finally 块中的 Monitor.Exit(temp) 执行之前发生线程中止或任何跨线程异常 - 那会保持对象上的锁定吗?
在这个级别是否有可能发生异常,使对象仍处于锁定状态?
Monitor.Exit(temp)
在 4.0 实现中,如果在 finally 块执行之前发生线程中止或任何跨线程异常- 那会保持对象上的锁定吗?
让我们看一下该代码,以便其他读者清楚:
bool lockWasTaken = false;
var temp = obj;
try
{
Monitor.Enter(temp, ref lockWasTaken);
{
body
}
}
finally
{
if (lockWasTaken)
{
// What if a thread abort happens right here?
Monitor.Exit(temp);
}
}
您的问题无法回答,因为它基于错误的假设,即线程中止可能发生在 finally 块的中间。
线程中止不能发生在 finally 块的中间。这只是您永远不应该尝试中止线程的众多原因之一。整个线程可能在 finally 块中运行,因此不可中止。
在这个级别是否有可能发生异常,使对象仍处于锁定状态?
不会。线程中止将被延迟,直到控制权离开 finally。解锁有效锁不会分配内存或引发另一个异常。
引发此异常时,运行时会在结束线程之前执行所有finally块
(这包括调用时当前正在执行的任何finally
块)Thread.Abort
所以是的,锁仍然会被释放。不过,这是否可取是一个非常不同的问题——你不知道线程即将释放锁——它可能在任何地方,并且可能正在改变锁保护的状态——与往常一样,建议是避免Thread.Abort
.