假设我有以下代码:
public class SomeClass()
{
private readonly object _lock = new object();
public void SomeMethodA()
{
lock (_lock)
{
SomeHelperMethod();
//do something that requires lock on _lock
}
}
public void SomeMethodB()
{
lock (_lock)
{
SomeHelperMethod();
//do something that requires lock on _lock
}
}
private void SomeHelperMethod()
{
lock (_lock)
{
//do something that requires lock on _lock
}
}
}
在SomeHelperMethod
中加锁似乎是多余和浪费的,因为所有调用者已经获得了锁。然而,仅仅从 SomeHelperMethod
中删除锁可能是危险的,因为我们以后可能会重构代码并忘记在调用SomeHelperMethod
之前对_lock
对象加锁。
理想情况下,可以通过在SomeHelperMethod
内部断言当前线程拥有_lock
锁来解决这个问题:
private void SomeHelperMethod()
{
Debug.Assert(Monitor.HasLock(_lock));
//do something that requires lock on _lock
}
但是似乎没有这样的方法。Monitor.TryEnter
并没有帮助,因为锁是可重入的。因此,如果当前线程已经拥有锁,则TryEnter
仍将成功并返回true
。它失败的唯一时间是另一个线程拥有锁且调用超时。
那么,是否存在这样的方法?如果没有,为什么?在我看来,这似乎并不危险,因为它仅告诉您当前线程(而不是另一个线程)是否拥有锁。
Assert
方法和Contract
类,以调试涉及Monitor
类的锁定问题。" - Kent Boogaart