Простой способ разрешить только один поток доступа к ресурсу в C #? - PullRequest
0 голосов
/ 27 ноября 2011

Как заменить этот код:

try
{
    lock (lockForSomethingInUse)
    {
        somethingInUse = true;
        // use it
    }
}
finally
{
    somethingInUse = false;
}

На:

using (lockForSomething)
{
   // use it
}

Ответы [ 4 ]

4 голосов
/ 27 ноября 2011

lock() уже генерирует блок try / finally под капотом, поэтому просто удалите его, и все будет хорошо

1 голос
/ 27 ноября 2011

Если вы хотите использовать lock и узнать, действительно ли блокировка получена в данный момент с использованием только одного оператора / переменной, вы можете попробовать использовать следующие классы. Они не принесут вам никаких наград за удобочитаемость, но они позволят вам использовать using для блокировки, как вы хотели.

class DisposableLock
{
    public bool IsAcquired { get; set; }

    class Handle : IDisposable
    {
        private DisposableLock parent;

        public void Dispose()
        {
            parent.IsAcquired = false;
            Monitor.Exit(parent);
        }
    }

    public IDisposable Acquire()
    {
        var handle = new Handle();
        handle.parent = this;
        handle.parent.IsAcquired = true;
        Monitor.Enter(this);
        return handle;
    }
}

Использование:

DisposableLock lockForSomething = new DisposableLock();
// ...

using (lockForSomething.Acquire())
{
// do something
}

Затем вы можете использовать lockForSomething.IsAcquired в другом месте, чтобы проверить, используется ли ресурс. Внутренний класс, реализующий IDisposable, должен убедиться, что вы не будете случайно использовать using (lockForSomething).

0 голосов
/ 27 ноября 2011

Не произойдет сбой, даже если произойдет исключение, потому что:

lock (x) ...

совпадает с:

System.Threading.Monitor.Enter(x);
try {
   ...
}
finally {
   System.Threading.Monitor.Exit(x);
}

Оператор блокировки в MSDN

0 голосов
/ 27 ноября 2011

Этот код:

using (lockForSomething) 
{ 
   // use it 
}

Подразумевает, что lockForSomething удаляется при выходе из блока использования кода.Если lockForSomething не относится к более широкой области (нет, нет!), То другой поток не сможет получить к нему доступ.

...