Edwin Evans
Edwin Evans

Reputation: 2836

Simple way to only allow one thread access to resource in C#?

How can I replace this code:

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

With:

using (lockForSomething)
{
   // use it
}

Upvotes: 0

Views: 582

Answers (4)

user418938
user418938

Reputation:

If you want to use lock and be able to know whether lock is actually acquired at the moment with using only one statement/variable, you can try using following classes. They won't win you any awards for readability, but they allow you to use using for locking as you wanted.

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;
    }
}

The usage:

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

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

You can then use lockForSomething.IsAcquired in some other place to check if resource is being used. The inner class implementing IDisposable is to make sure you won't by accident use using (lockForSomething).

Upvotes: 1

Michał Powaga
Michał Powaga

Reputation: 23173

It won't fail even if the exception happen, because:

lock (x) ...

is the same as:

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

The lock statement on MSDN

Upvotes: 0

rfmodulator
rfmodulator

Reputation: 3738

This code:

using (lockForSomething) 
{ 
   // use it 
}

Implies that lockForSomething is disposed when the using code block exits. Unless lockForSomething belongs to a broader scope (no no!), then there is no way a different thread can access it.

Upvotes: 0

sll
sll

Reputation: 62484

lock() already generates try/finally block under the hood so just remove it and all would be fine

Upvotes: 4

Related Questions