如何检测对象是否被锁定或没有?
Monitor.TryEnter
(如在描述有没有办法如果一个对象被锁定检测? )不适合我,因为它锁定的对象,如果它没有被锁定工作。
我只是想检查,如果它被锁定,其他地方在我的代码,我将使用Monitor
类锁定对象。
我知道这是可以使用例如一个布尔字段(例如private bool ObjectIsLocked
),但用什么样的锁对象本身检测到它。
下面的示例代码显示了我想做的事:
private static object myLockObject = new object();
private void SampleMethod()
{
if(myLockObject /*is not locked*/) // First check without locking it
{
...
// The object will be locked some later in the code
if(!Monitor.TryEnter(myLockObject)) return;
try
{
....
}
catch(){...}
finally
{
Monitor.Exit(myLockObject);
}
}
}
你这样做是错误的 。 如果你没有在对象上的锁,你不能检查,如果它被锁定(如果你有锁,你会提前知道)。 你可以在“问”“被锁定?” 并获得了“不”作为回应,然后在接下来的纳秒另一个线程可以把锁,你的程序将处于损坏状态进入。 这根本就不是去多线程应用程序和.NET为什么没有理由的方式Monitor.IsLocked
方法。 如果你的代码需要检查锁之前获取它让你有一个设计问题。 试图与未受保护的标志,以解决它是偶然的,是行不通的100%保证一个贫穷的解决方案。
总之,不要使用bool
VAR信号多线程锁定状态(因为你可以有同样的问题,你看“假”和1纳秒后另一个线程会写“真”的话)。 使用Interlock.CompareExchange
。
private static int _lockFlag = 0; // 0 - free
if (Interlocked.CompareExchange(ref _lockFlag, 1, 0) == 0){
// only 1 thread will enter here without locking the object/put the
// other threads to sleep.
Monitor.Enter(yourLockObject);
// free the lock.
Interlocked.Decrement(ref _lockFlag);
}
你会看到,你需要改变_lockFlag上每一个地方的锁给你的对象可能获得性的地方 。 换句话说,你将构建各地土特产一个自定义锁系统。
Monitor.IsEntered应该做的伎俩。
编辑:我只是重新阅读文档,并说:
确定当前线程是否在指定的对象上的锁。
所以这是不够的,因为你可能会想知道是否有不同的线程持有的锁?
有没有办法在C#中Monitor类来做到这一点
只要使用;
var lockedBySomeoneElse = !Monitor.TryEnter(obj);
if (!lockedBySomeoneElse) Monitor.Exit(obj);
// the variable 'lockedBySomeoneElse' has the info you want
像readerwriterlockslim其他锁具企业没有真正的帮助。 那人能告诉你如何可能的读者也有,但如果有一个作家忙;-(
此外,如果您使用自己的建议,“私人布尔ObjectIsLocked”,这是我走的路线,我认为,你应该使用
private volatile bool ObjectIsLocked
这将使C#与多线程的更新更好地反映更改。
如果你想确保对象仍然是可锁定以后,只需拨打TryEnter
并保持锁定的全部时间。 否则,如果你想稍后再尝试锁定对象,只需调用TryEnter
并立即解开它,如果它是锁着的。
Techincally您可以检查它有关联的分配懒洋洋结构的同步块的排列索引对象的同步区块索引字段-每个对象都有这个领域和每一个对象,它用于synchronziation,有这个字段集。 这些结构用于协调线程同步。 不过,我很怀疑,你将能够在不分析API来访问这些信息。
我绝不主张检查锁然后输入代码块。 然而,我发现这个线程,同时寻找一种方式来检查新的功能不能离开锁定的对象。 基于Monitor.IsEntered单元测试让我正是我一直在寻找。