有没有办法检测对象是否被锁定?

时间:2009-08-19 14:08:20

标签: multithreading c#-3.0

有没有办法确定某个对象是否在C#中被锁定?我有一个不值得羡慕的位置,通过设计,我从一个类中的队列中读取,我需要将内容转储到类中的集合中。但是该集合也是从类外的接口读/写的。所以很明显可能存在写入集合的情况,就像我想要写入它一样。

我可以围绕它进行编程,比如使用委托,但这会很难看。

5 个答案:

答案 0 :(得分:42)

您始终可以使用值0为TryEnter method上的静态Monitor class调用等待的值。如果它被锁定,那么该调用将返回false。

但是,这里的问题是您需要确保您尝试同步访问权限的列表被锁定在自身以便同步访问。

使用正在同步访问的对象作为要锁定的对象(暴露对象的太多内部细节)通常是不好的做法。

请记住,锁可以是其他任何东西,所以只要在该列表上调用它就没有意义,除非你确定该列表是被锁定的。

答案 1 :(得分:11)

如果对象未锁定,

Monitor.TryEnter将成功,如果此时此对象被锁定,则返回false。但请注意,这里有一个隐含的竞争:此方法返回的实例,对象可能不再被锁定。

答案 2 :(得分:7)

我不确定对时间为0的TryEnter进行静态调用是否可以保证在可用锁定时不会获取锁定。我在调试模式下测试同步变量被锁定的解决方案是使用以下方法:

#if DEBUG
// Make sure we're inside a lock of the SyncRoot by trying to lock it.
// If we're able to lock it, that means that it wasn't locked in the first
// place.  Afterwards, we release the lock if we had obtained it.
bool acquired = false;
try
{
    acquired = Monitor.TryEnter(SyncRoot);
}
finally
{
    if (acquired)
    {
        Monitor.Exit(SyncRoot);
    }
}
Debug.Assert(acquired == false, "The SyncRoot is not locked.");
#endif

答案 3 :(得分:6)

目前,您可以调用Monitor.TryEnter来检查对象是否被锁定。

在.NET 4.0中,CLR团队将添加“Lock inspection API”

以下是Rick Byers文章的引文:

  

锁定检查
  我们在ICorDebug中添加了一些简单的API,允许您探索托管锁(监视器)。例如,如果线程被阻塞等待锁定,您可以找到当前持有锁定的其他线程(如果有超时)。

因此,使用此API,您可以检查:
1)什么物体拿着锁?
2)谁在等待它?

希望这有帮助。

答案 4 :(得分:4)

Monitor.IsEntered

确定当前线程是否保持对指定对象的锁定 自4.5起可用