Extension methods for ReaderWriterLockSlim

Posted on

Problem

In current project I’m using a lot ReaderWriterLockSlim for synchronizing reading and writing values. Handling try { EnterReadLock(); .... } finaly { ExitReadLock(); } every time I need access value seems to me as copying code. So I created extension methods for ReaderWriterLockSlim which makes me coding much easer and faster (and reusable i think).

However I would like know, if you found some disadvantages in the extension methods I missed or forgot.
There are three extension methods:

  • ReadOnly<T>(this ReaderWriterLockSlim self, Func<T> readFunc) // calls EnterReadLock()
  • Read<T>(this ReaderWriterLockSlim self, Func<T> readFunc) // calls EnterUpgradeableReadLock()
  • Write(this ReaderWriterLockSlim self, Action writeAction) // calls EnterWriteLock()
  • Write<T>(this ReaderWriterLockSlim self, Func<T> writeAction) // calls EnterWriteLock()

There is code of ReadOnly<T>(...) method. All methods looks similar.

public static T ReadOnly<T>(this ReaderWriterLockSlim self, Func<T> readFunc) {
    if (object.ReferenceEquals(self, null)) { throw new ArgumentNullException("self"); }
    if (object.ReferenceEquals(readFunc, null)) { throw new ArgumentNullException("readFunc"); }

    T result;

    // flag, if lock was entered
    bool lockEntered = false;
    try {
        // I don't want the ThreadAbortException during claiming the lock
        Thread.BeginCriticalRegion();
        try {
            self.EnterReadLock();
            lockEntered = true;
        }
        finally {
            Thread.EndCriticalRegion();
        }

        result = readFunc();
    }
    finally {
        // I don't want the ThreadAbortException during releasing the lock
        Thread.BeginCriticalRegion();
        try {
            if (lockEntered) {
                self.ExitReadLock();
            }
        }
        finally {
            Thread.EndCriticalRegion();
        }
    }

    return result;
}

Solution

It looks pretty good. I can’t see anything less than great.
I’d just add that to your code:

    private static void Critical(Action criticalAction)
    {
        try
        {
            Thread.BeginCriticalRegion();
            criticalAction();
        }
        finally
        {
            Thread.EndCriticalRegion();
        }
    }

And i used the IsWriteLockHeld, IsReadLockHeld, etc, before exiting the lock.

Leave a Reply

Your email address will not be published. Required fields are marked *