Threading – Using ReaderWriterLockSlim

Yan Cui

I help clients go faster for less using serverless technologies.

When dealing with concurrency/threading issues in .Net, the normal approach is to use lock() to lock a dedicated sync object like this:

private static readonly object padlock = new object();
…
lock(padlock)
{
     // enter critical section here
}

This is an efficient, simple and well proven way to get thread-safety in .Net and is probably all you’ll ever need in your project. However, as this approach ensures only one thread can enter the critical section at any one time it’s not ideal for managing access to a shared resource because all read and write operations must be made sequentially and this results in a performance hit on your application. Ideally all threads should be able to read the shared resource simultaneously but only one thread can update it and no other threads can read from the resource whilst the update is happening.

.Net’s answer to this used to be the ReaderWriterLock, which since .Net 3.5 has been superseded by the better, more lightweight and performing ReaderWriterLockSlim which Microsoft is recommending for all new development.

The ReaderWriterLockSlim has three modes: Read, Ungradeable and Write:

  • many threads can enter Read lock simultaneously
  • only one thread can enter Ungradeable lock but other threads can still enter Read lock
  • only one thread can enter Write lock and no other thread can enter any lock

In practice though, almost all threading problems can be solved using read and write locks alone. To enter read/write lock, you need something like this:

private static readonly ReaderWriteLockSlim rwlock = new ReaderWriterLockSlim();
…
rwlock.EnterReadLock()
try
{
     // do something here
}
finally
{
     // don't forget to release the lock afterwards!
     rwlock.ExitReadLock();
}

As you can see, this can seriously clutter your code if you require read/write locks in many places! I saw this post on StackOverflow quite some time back and really like the pattern that Marc has presented:

http://stackoverflow.com/questions/170028/how-would-you-simplfy-entering-and-exiting-a-readerwriterlock

In his answer he showed how you can simplify the code needed to enter a read lock, here’s the full implementation you can use in your project:

public static class ReaderWriterLockSlimExtensions
{
     private sealed class ReadLockToken : IDisposable
     {
          private ReaderWriterLockSlim _sync;
          public ReadLockToken(ReaderWriterLockSlim sync)
          {
               _sync = sync;
               sync.EnterReadLock();
          }
          public void Dispose()
          {
               if (_sync != null)
               {
                    _sync.ExitReadLock();
                    _sync = null;
               }
          }
     }
     private sealed class WriteLockToken : IDisposable
     {
          private ReaderWriterLockSlim _sync;
          public WriteLockToken(ReaderWriterLockSlim sync)
          {
               _sync = sync;
               sync.EnterWriteLock();
          }
          public void Dispose()
          {
               if (_sync != null)
               {
                    _sync.ExitWriteLock();
                    _sync = null;
               }
          }
     }

     public static IDisposable Read(this ReaderWriterLockSlim obj)
     {
          return new ReadLockToken(obj);
     }
     public static IDisposable Write(this ReaderWriterLockSlim obj)
     {
          return new WriteLockToken(obj);
     }
}

And to use it in your code, this is all you’ll need:

using (_sync.Read())
{
     // do reading here
}
using (_sync.Write())
{
     // do writing here
}

Further Readings:

Jon Skeet’s tutorial on Multi-Threading in .Net

Ayande has a post on using the UpgradeableReadLock


 

Whenever you’re ready, here are 4 ways I can help you:

  1. If you want a one-stop shop to help you quickly level up your serverless skills, you should check out my Production-Ready Serverless workshop. Over 20 AWS Heroes & Community Builders have passed through this workshop, plus 1000+ students from the likes of AWS, LEGO, Booking, HBO and Siemens.
  2. If you want to learn how to test serverless applications without all the pain and hassle, you should check out my latest course, Testing Serverless Architectures.
  3. If you’re a manager or founder and want to help your team move faster and build better software, then check out my consulting services.
  4. If you just want to hang out, talk serverless, or ask for help, then you should join my FREE Community.

 


3 thoughts on “Threading – Using ReaderWriterLockSlim”

  1. i easily love your own posting choice, very remarkable.
    don’t give up as well as keep creating simply because it simply very well worth to follow it.
    impatient to browse a whole lot more of your current article content, good bye ;)

  2. Pingback: Threads – Nitesh Kumar

Leave a Comment

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