Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to implement scoped lock in C#?

Tags:

c#

locking

A common pattern in C++ is to create a class that wraps a lock - the lock is either implicitly taken when object is created, or taken explicitly afterwards. When object goes out of scope, dtor automatically releases the lock. Is it possible to do this in C#? As far as I understand there are no guarantees on when dtor in C# will run after object goes out of scope.

Clarification: Any lock in general, spinlock, ReaderWriterLock, whatever. Calling Dispose myself defeats the purpose of the pattern - to have the lock released as soon as we exit scope - no matter if we called return in the middle, threw exception or whatnot. Also, as far as I understand using will still only queue object for GC, not destroy it immediately...

like image 751
Sergey Avatar asked Nov 02 '08 11:11

Sergey


People also ask

What is scoped lock?

First introduced in the 2017 standard, the scoped lock is a mutex wrapper which obtains access to (locks) the provided mutex, and ensures it is unlocked when the scoped lock goes out of scope. It differs from a lock guard in that it is a wrapper for not one, but multiple mutexes.

How do you lock a method in C#?

The lock statement acquires the mutual-exclusion lock for a given object, executes a statement block, and then releases the lock. While a lock is held, the thread that holds the lock can again acquire and release the lock. Any other thread is blocked from acquiring the lock and waits until the lock is released.

Why do we lock objects in C#?

The lock keyword is used to get a lock for a single thread. A lock prevents several threads from accessing a resource simultaneously. Typically, you want threads to run concurrently. Using the lock in C#, we can prevent one thread from changing our code while another does so.

What is lock in .NET core?

The Lock statement is used in threading, that limit the number of threads that can perform some activity or execute a portion of code at a time. Exclusive locking in threading ensures that one thread does not enter a critical section while another thread is in the critical section of the code.


1 Answers

To amplify Timothy's answer, the lock statement does create a scoped lock using a monitor. Essentially, this translates into something like this:

lock(_lockKey)
{
    // Code under lock
}

// is equivalent to this
Monitor.Enter(_lockKey)
try
{
     // Code under lock
}
finally
{
    Monitor.Exit(_lockKey)
}

In C# you rarely use the dtor for this kind of pattern (see the using statement/IDisposable). One thing you may notice in the code is that if an async exception happens between the Monitor.Enter and the try, it looks like the monitor will not be released. The JIT actually makes a special guarantee that if a Monitor.Enter immediately precedes a try block the async exception will not happen until the try block thus ensuring the release.

like image 200
denis phillips Avatar answered Sep 19 '22 03:09

denis phillips