.net Monitor.TryEnter(对象)和Monitor.TryEnter(对象,参考布尔)之间存在什么重要区别?

.net Monitor.TryEnter(对象)和Monitor.TryEnter(对象,参考布尔)之间存在什么重要区别?,.net,multithreading,.net-4.0,synchronization,monitor,.net,Multithreading,.net 4.0,Synchronization,Monitor,似乎这些代码片段的行为应该相同: 1:Monitor.TryEnter(对象) 2:Monitor.TryEnter(对象,引用bool)-在.NET4.0中引入 我从MSDN文档中看到: 如果锁不是因为 抛出异常时,变量 为LockTake参数指定 此方法结束后,为false。这 允许程序在 所有情况下,是否有必要 松开锁 但文档中还指出,仅使用对象参数的重载不会引发除ArgumentNullException之外的任何异常。因此,如果在上面的代码段1中抛出异常,这可能只是因为lockObje

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

1:Monitor.TryEnter(对象) 2:Monitor.TryEnter(对象,引用bool)-在.NET4.0中引入 我从MSDN文档中看到:

如果锁不是因为 抛出异常时,变量 为LockTake参数指定 此方法结束后,为false。这 允许程序在 所有情况下,是否有必要 松开锁

但文档中还指出,仅使用
对象
参数的重载不会引发除
ArgumentNullException
之外的任何异常。因此,如果在上面的代码段1中抛出异常,这可能只是因为
lockObject
null
,在这种情况下,没有锁定(并且
TryEnter
将返回
false
),因此不需要调用
Monitor.Exit

显然,他们不会无缘无故地引入这种过载。那么,
Monitor.TryEnter(object,ref bool)
方法打算解决什么场景呢

  • Monitor.TryEnter可能会成功,然后会触发一个异步异常,如ThreadAbortException或OutOfMemoryException(可能在没有可见分配的情况下发生)。然后锁会被拿走,但永远不会被释放

  • 请看:

    哇,这花了一段时间。这种方法只出现在.NET4中。不过,这两种重载不是都是这样吗?也就是说,第二次过载将如何防止这种情况?哦,我明白了(访问了链接)。。。因此,换句话说,可以在
    TryEnter
    之后,但在进入
    try
    /
    finally
    块之前抛出异常。明白了。可惜没有“好”的方法将类似的逻辑应用于“使用”样式的块。在构造函数执行任何需要撤消的操作之前,它可能会让构造函数“偷偷溜出”对部分构造的对象的引用,并且只能从工厂方法调用构造函数,该工厂方法可以使用偷偷溜出的引用来处理部分构造的对象,但如果有更好的方法,那就更好了。可能会更改框架,以便在实现iDisposeOnConstructorException的对象上构建失败时,框架将在其上调用iDOCE.dispose?当前JIT包含一个使“潜逃”场景不可能发生的攻击。您也可以自己使用块重新实现:C=null;试试{c=newc();}最后{if(c!=null)c.Dispose();}@usr:我不认为“偷偷溜出去”是不可能的;如果包含任何
    IDisposable
    字段的最深基类的构造函数采用类型为
    IDisposable
    ref
    参数,并将
    复制到该参数,并且所有派生类构造函数都包含类似的参数并将其传递给其父类,然后,即使在参数赋值和构造函数退出之间的某个时间发生异常,调用代码也可以使用正在构造的对象。这是一个难题,但这是我知道的唯一安全的方法来确保事情得到清理。
    if (Monitor.TryEnter(lockObject))
    {
        try
        {
            DoSomething();
        }
        finally
        {
            Monitor.Exit(lockObject);
        }
    }
    
    bool lockAcquired;
    try
    {
        Monitor.TryEnter(lockObject, ref lockAcquired);
        if (lockAcquired)
        {
            DoSomething();
        }
    }
    finally
    {
        if (lockAcquired)
        {
            Monitor.Exit(lockObject);
        }
    }