可以Monitor.Enter抛出异常吗?

pal*_*now 5 c# multithreading synchronization

可以Monitor.Enter抛出任何异常.我正在进行代码审查,Monitor.Enter并在try块之前找到它.你看到有什么问题吗?

Monitor.Enter(...)
try
{
    ...
}
finally
{
    Monitor.Exit(..)
}
Run Code Online (Sandbox Code Playgroud)

Hen*_*man 13

这是正确的模式,无论是Enter()投掷(可以投掷)还是不投掷.

只有在调用Enter()成功之后,您的代码才有责任致电Exit().

假设呼叫Enter()失败.然后调用相应的Exit()是不正确的,这将使事情变得更糟.所以Enter()必须在try块之外(之前).


Eri*_*ert 10

Hans Passant的评论当然是正确的.如果锁定之前Monitor.Enter抛出,那么你希望finally运行.如果在进行锁定输入并输入尝试抛出,则锁定被释放.(稍后会详细介绍.)但是如果在进行锁定之后但输入尝试之前发生了抛出,则永远不会清除锁定.

这是一种罕见但可能的情况.

在C#4中,我们更改了lock语句的codegen,以便监视器输入在try中.这可确保在锁定后抛出某些东西时始终释放锁定.但请注意,这可能仍然是错误的.如果在锁定之后抛出某些东西,那么锁保护的任何非原子突变都可能是半完成的,然后finally块解锁锁定并允许访问不一致的状态!这里的根本问题是你不应该首先扔进锁内.

有关此问题,请参阅我的文章以获取更多讨论