Monitor.TryEnter和lock()一起工作吗?

时间:2011-11-18 15:44:15

标签: c# multithreading locking thread-safety

我正在查看已创建的代码,它在一个方法调用中使用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
    }
}

这可以吗?

3 个答案:

答案 0 :(得分:9)

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对象这样公开的东西被认为是糟糕的形式。)

答案 1 :(得分:5)

是的,这两个结构将协同工作。 C#lock关键字只是Monitor.EnterMonitor.TryEnter方法的精简包装。

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

答案 2 :(得分:2)

lock将阻止,直到资源可用

TryEnter如果已被锁定,则不会执行任何操作。

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

在你的情况下f2()无论花费多长时间,总会做任何事情。如果存在锁定争用,f1()将立即返回