【问题标题】:Is there a way to detect if an object is locked?有没有办法检测对象是否被锁定?
【发布时间】:2010-11-20 23:23:43
【问题描述】:

有什么方法可以确定一个对象是否在 C# 中被锁定?我有一个令人羡慕的位置,通过设计,我从类内的队列中读取,我需要将内容转储到类中的集合中。但是该集合也可以从类外的接口读取/写入。所以很明显,当我想写入集合时,可能会出现这样的情况。

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

【问题讨论】:

  • 是的,谢谢大家。这几乎证实了我的想法。

标签: multithreading c#-3.0


【解决方案1】:

Monitor.IsEntered

判断当前线程是否持有指定对象的锁。
从 4.5 开始可用

【讨论】:

    【解决方案2】:

    我不确定是否对时间为 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
    

    【讨论】:

    • 变量isNotLocked 的命名相当糟糕。如果isNotLocked 为真,则解锁 - 虽然从技术上讲它是正确的,因为当成功获取锁时isNotLocked 将为真,上面的代码真的很难阅读。如果其他人必须为此工作,他将有一个 WTF 时刻。
    • 如果正在运行的线程与拥有锁的线程相同,则不起作用。它会说锁是空闲的,而实际上它不是。
    【解决方案3】:

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

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

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

    请记住,锁可以在其他任何东西上,因此除非您确定该列表是被锁定的对象,否则仅在该列表上调用它是没有意义的。

    【讨论】:

      【解决方案4】:

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

      在 .NET 4.0 CLR 团队将添加“锁检查 API”

      这里引用Rick Byers文章:

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

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

      希望这会有所帮助。

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 2012-12-23
          • 1970-01-01
          • 2020-11-05
          • 2016-10-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多