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

sco*_*eep 46 multithreading c#-3.0

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

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

cas*_*One 43

您可以随时调用静态TryEnter方法Monitor使用的价值等的值为0.如果它被锁定,则调用将返回false.

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

这是一般不好的做法,使用其访问已被同步的对象的对象锁定在(暴露过多的对象的内部细节).

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


Bar*_*lly 11

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


小智 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
Run Code Online (Sandbox Code Playgroud)

  • 变量`isNotLocked`命名相当糟糕.如果`isNotLocked`为真,你解锁 - 虽然从技术上说它是正确的,因为当成功获取锁时,`isNotLocked`将为真,上面的代码真的很糟糕.如果其他人必须为此工作,他将会有一个WTF时刻. (2认同)
  • 如果运行的线程与拥有锁的线程相同,则不起作用.它会说锁定是免费的,但事实并非如此. (2认同)

Ali*_*kau 6

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

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

以下是Rick Byers文章的引文:

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

因此,使用此API,您将能够检查:
1)什么对象持有锁?
2)谁在等待它?

希望这可以帮助.


use*_*528 6

Monitor.IsEntered

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