.net Monitor.TryEnter(对象)和Monitor.TryEnter(对象,参考布尔)之间存在什么重要区别?
似乎这些代码片段的行为应该相同: 1:Monitor.TryEnter(对象) 2:Monitor.TryEnter(对象,引用bool)-在.NET4.0中引入 我从MSDN文档中看到: 如果锁不是因为 抛出异常时,变量 为LockTake参数指定 此方法结束后,为false。这 允许程序在 所有情况下,是否有必要 松开锁 但文档中还指出,仅使用.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
对象
参数的重载不会引发除ArgumentNullException
之外的任何异常。因此,如果在上面的代码段1中抛出异常,这可能只是因为lockObject
为null
,在这种情况下,没有锁定(并且TryEnter
将返回false
),因此不需要调用Monitor.Exit
)
显然,他们不会无缘无故地引入这种过载。那么,Monitor.TryEnter(object,ref bool)
方法打算解决什么场景呢
请看:哇,这花了一段时间。这种方法只出现在.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);
}
}