Monday, 3 February 2014

Maintaining shared state with ReaderWriterLock(Slim) in c#


Although maintaining the shared state in a multi-threaded application  can be easily achieved with the use of  lock keyword in .net, but the use of  lock keyword is sometimes inefficient especially in a high performance application because of the reckless way in which locks are applied. Threads can either be accessing a shared state to carry out any of these functions read, write or sometimes (but less often) read  and write (ie: update), these states are not distinguished in locks leading to its application in unnecessary places in the code base.

Main discussion

The ReaderWriterLock(Slim) object can be used in all the states stated above and is usually more efficient to use than ordinary locks, because its use aides in niche locking and with the required lock for a given for every mode. What this means is that the use of ReaderWriterLock(Slim) by the virtue of its name can be applied according to the desired operation that the thread wants to carry out.

Now this object exists in two variations: the old and more primitive ReaderWriterLock object and the ReaderWriterLockSlim object that was implemented in the .net framework version 3.5. In this post, I will try to enlighten you on the use of the ReaderWriterLockSlim object which is the most popular one and the one advised to be used by .net development team unless you are dealing with framework that was implemented in .net framework less than 3.5.

When you want to implement ReaderWriterSlim object, you just new up the class using the default parameterless constructor as shown below.

                         ReaderWriterLockSlim _rw = new ReadWriterSlim();

After newing up this object, you either lock the accessed shared state either in read mode or in write mode (how cool is that) also there is a third but not so obvious mode in which the state can be put in which is the read and update mode (by upgrading the read state, more on this later).

To acquire a read access, you will simply call the _rw.EnterReadLock() (or its TryXXXX() variant which takes in an int timeout value and returns a bool to indicate result). When using the old version you can achieve the same effect by calling AcquireReadLock() instance method of the ReaderWriterLock object. A shared state that is in the Read mode can be accessed by multiple threads at the same time with the sole objective of reading from it. When a thread wants to write to the shared state, all the threads currently reading from the state must be exited before the thread can proceed. This can be achieved by calling _rw.ExitReadLock() (or ReleaseReadLock() in ReaderWriterLock version).

Furthermore, to acquire a write access, you call _rw.EnterWriteLock() (for the old version AcquireWriteLock()). This method tries to put the shared state in a write mode and will only succeed if there is no thread reading from the state. Also, you can use the TryXXXX() version which like its ReadLock counterpart accepts a timeout value and informs the caller on the success/failure status of the operation. Now when the WriteLock has been acquired, exclusive write access is then given to the thread that acquired the lock, thereby guaranteeing atomic write operation.

Finally when I thread wants to read from and write to a shared state at the same time, the ReadLock can be upgraded by calling EnterUpgradeableReadLock() method. This method will try to put the lock in a write mode so that the state can be written to. One thing that is worthy of note is that it is only one thread can be in upgradeable mode at a time.

There are several other status monitoring methods and properties that was added to the ReaderWriterLockSlim class but I encourage you to pay a visit to MSDN documentation for an in-dept explanation and research.

In this post, I have tried to explain when and how to utilize the ReaderWriterSlim object which was added in .net framework version 3.5. in your codes. I hope that after reading this post you will be armed with another tool with which to tackle the synchronization beast which one encounters when writing multi-threaded application in C#. For further research of this object I highly encourage you to visit the links listed below.

 Happy coding.

No comments:

Post a Comment