A boolean lock using IDisposable

While there are more complex and functional lock mechanisms, I wanted a very simple lock that would tell me if an operation was locked or not. Normally I would just have a flag that’d be true or false, but I found that it was not always easy to remember to set the flag on or off, and also to make sure the flag was set at the right place. So I came up with this class :

public class BooleanLock
{
    public bool Locked { get; private set; }

    public class BlockLock : IDisposable
    {
        private BooleanLock _parent;

        public BlockLock(BooleanLock parent)
        {
            _parent = parent;
            _parent.Locked = true;
        }

        #region IDisposable Members

        public void Dispose()
        {
            _parent.Locked = false;
        }

        #endregion
    }

    public BlockLock Lock()
    {
        return new BlockLock(this);
    }
}

Now I could use it this way :

// Declare a field as a lock
private BooleanLock _myUpdateLock = new BooleanLock();

// Check for lock
private void UpdateSomeProperty(bool reset)
{
    if (_myUpdateLock.Locked)
        return;

    // . . .

And here’s where the lock is set :

// Part of the function is not re-entrant, so we use a lock there
private void OnSomePropertyChanged()
{
    if (some-condition)
    {
        using (_myUpdateLock.Lock())
        {
            // do non-re-entrant stuff
        } <-- lock is released here automatically

The big advantage here is that the C# compiler’s using-block behavior handles complex trycatch scenarios that I would otherwise have had to implement on my own.

Advertisements

6 thoughts on “A boolean lock using IDisposable

  1. Assuming there is more than one place or thread where the lock may be taken, you need to check the lock and take it in one atomic operation (this requires OS support in the thread scheduler). As implemented above, there is a race condition that can result in two threads thinking they hold the lock:

    Thread A checks the lock and sees that it is not taken.
    Immediately following this, thread B runs and takes the lock.
    While thread B still holds the lock, thread A runs and proceeds to take the lock (it thinks the lock has not been taken–remember, it wasn’t taken when thread A checked the status).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s