【问题标题】:Does Monitor.TryEnter and lock() work together?Monitor.TryEnter 和 lock() 一起工作吗?
【发布时间】:2011-11-18 15:44:15
【问题描述】:

我正在查看已创建的代码,它在一个方法调用中使用 TryEnter 并锁定其他方法。所以,像这样:

private readonly object xmppLock = new object();

void f1() 
{
    if (Monitor.TryEnter(xmppLock))
    {
        try
        {
            // Do stuff
        }
        finally
        {
            Monitor.Exit(xmppLock);
        }
    }
}

void f2()
{
    lock(xmppLock)
    {
        // Do stuff
    }
}

这样好吗?

【问题讨论】:

    标签: c# multithreading locking thread-safety


    【解决方案1】:

    锁会阻塞直到资源可用

    TryEnter 如果已经被锁定,将不会做任何事情。

    根据您的需要,您必须使用其中一种。

    在您的情况下,f2() 将永远做它所做的一切,无论需要多长时间。 f1()如果有锁竞争会立即返回

    【讨论】:

    【解决方案2】:

    lock 只是Monitor.Enter 的语法糖,所以是的,它可以正常工作。

    The Visual Basic SyncLock and C# lock statements use Monitor.Enter to take the lock and Monitor.Exit to release it. The advantage of using the language statements is that everything in the lock or SyncLock block is included in a Try statement.

    (也就是说,锁定像Type 对象这样的公共对象被认为是一种糟糕的形式。)

    【讨论】:

    • 这没有回答 OP 使用的 TryEnter
    • 很明显,在一个地方使用TryEnter 获取锁将与在另一个地方使用Enter 获取它一起工作,所以不值得纠结。
    【解决方案3】:

    是的,这两个结构可以一起工作。 C# lock 关键字只是对 Monitor.EnterMonitor.TryEnter 方法的一个薄包装。

    注意:我绝对会避免使用 Type 实例作为锁定值。这样做非常脆弱,因为它很容易让两段完全不相关的代码意外地锁定在同一个对象上。这可能导致死锁。

    【讨论】:

    • 感谢关于 typeof() 的指针。我对此提出了不同的问题,因为我不明白它在做什么,因为它不是我正在编辑的代码,我想确保我知道发生了什么。
    猜你喜欢
    • 1970-01-01
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 2010-10-20
    • 2012-01-17
    • 2013-07-09
    • 2016-01-29
    • 2017-02-07
    相关资源
    最近更新 更多