Monitor.TryEnter(object)和Monitor.TryEnter(object,ref bool)之间存在什么重要的区别?

时间:2010-09-09 07:42:27

标签: .net multithreading .net-4.0 synchronization monitor

似乎这些代码片段的行为应该相同:

1:Monitor.TryEnter(object)

if (Monitor.TryEnter(lockObject))
{
    try
    {
        DoSomething();
    }
    finally
    {
        Monitor.Exit(lockObject);
    }
}

2:Monitor.TryEnter(object,ref bool) - 在.NET 4.0中引入

bool lockAcquired;
try
{
    Monitor.TryEnter(lockObject, ref lockAcquired);
    if (lockAcquired)
    {
        DoSomething();
    }
}
finally
{
    if (lockAcquired)
    {
        Monitor.Exit(lockObject);
    }
}

我在the overload taking a ref bool parameter上的MSDN文档中看到:

  

如果因为没有采取锁定   异常被抛出,变量   为 lockTaken 参数指定的   此方法结束后 false 。这个   允许程序确定,在   所有情况下,是否有必要   释放锁。

但是文档表明只有object参数的重载不会引发除ArgumentNullException以外的任何异常。因此,如果在上面的代码段 1 中抛出了异常,它可能只是因为lockObjectnull,在这种情况下没有锁定(和{{无论如何,1}}都会返回TryEnter),因此不需要false来电。

显然,他们不会毫无理由地引入这种过载。那么Monitor.Exit方法旨在解决什么情况?

1 个答案:

答案 0 :(得分:7)

  1. Monitor.TryEnter可以成功,然后触发一个异步异常,如ThreadAbortException或OutOfMemoryException(可能在没有可见分配的情况下发生)。然后锁定将被采取但从未被释放。
  2. 请参阅:Locks and exceptions do not mix