Monitor.Enter
可以抛出任何异常。我正在进行代码审查,并在try block之前发现Monitor.Enter
。你看到有什么问题吗?
Monitor.Enter(...)
try
{
...
}
finally
{
Monitor.Exit(..)
}
答案 0 :(得分:13)
这是正确的模式,无论Enter()
是否抛出(可以抛出)。
只有在致电Enter()
成功后,您的代码才有权致电Exit()
。
假设对Enter()
的调用失败。然后调用相应的Exit()
是不正确的,这将使事情变得更糟。所以Enter()
必须在try块之外(之前)。
答案 1 :(得分:10)
Hans Passant的评论当然是正确的。如果Monitor.Enter
在锁定之前抛出,那么您不希望最终运行。如果在之后引发并且在之后输入了尝试,则释放锁定。 (稍后详细介绍。)但是如果在锁定之后发生抛出但之前输入了尝试,那么锁定永远不会被清除。
This is a rare but possible situation.
在C#4中,我们更改了lock语句的codegen,以便监视器输入在try中。这可确保在锁定后抛出某些东西时始终释放锁定。但是,请注意这可能仍然是错误的。如果在锁定之后抛出某些东西,则锁定正在保护的任何非原子突变可能是半完成的,然后finally块解锁锁定并允许访问不一致的状态!这里的根本问题是你不应该首先扔进锁内。
有关详细讨论,请参阅my article about the issue。
答案 2 :(得分:1)
Monitor.Enter
至少可以抛出以下异常
null
Enter
的线程调用了它的Interrupt
方法。答案 3 :(得分:0)
如果它获得了锁定,那么没有。
但可能会在Monitor.Enter
和try
块之间抛出异常。
推荐的方法是新的Enter方法,.NET 4中的新方法:
public static void Enter( obj, ref bool lockTaken )