Работают ли Monitor.TryEnter и lock () вместе? - PullRequest
5 голосов
/ 18 ноября 2011

Я смотрю на код, который был создан, и он использует 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 ]

9 голосов
/ 18 ноября 2011

lock - это просто синтаксический сахар для Monitor.Enter, так что да, он будет работать нормально.

Операторы блокировки Visual Basic SyncLock и C # используют Monitor.Enter для взятия блокировки и Monitor.Exit для ее снятия. Преимущество использования операторов языка состоит в том, что все в блокировке или блоке SyncLock включено в инструкцию Try.

(При этом считается плохой формой блокировать что-то общедоступное, например, Type объект.)

5 голосов
/ 18 ноября 2011

Да, эти две конструкции будут работать вместе. Ключевое слово C # lock - это просто оболочка над методами Monitor.Enter и Monitor.TryEnter.

Примечание: я бы совершенно не использовал экземпляр Type в качестве значения для блокировки. Это очень хрупко, поскольку очень легко две совершенно не связанные друг с другом части кода неожиданно блокируются на одном и том же объекте. Это может привести к тупикам.

2 голосов
/ 18 ноября 2011

блокировка блокируется до тех пор, пока ресурс не станет доступен

TryEnter не будет ничего делать, если он уже заблокирован.

В зависимости от ваших потребностей вы должны использовать один илидругой.

В вашем случае f2() всегда будет делать то, что когда-либо, независимо от того, сколько времени это займет.f1() немедленно вернется, если возникнет конфликт блокировки

...