Introduction 
The .NET 
Framework provides several threading locking primitives. The ReaderWriterLock is 
one of them.
The ReaderWriterLock class is used to 
synchronize access to a resource. At any given time, it allows concurrent read 
access to multiple (essentially unlimited) threads, or it allows write access 
for a single thread. In situations where a resource is read frequently but 
updated infrequently, a ReaderWriterLock will provide much better throughput 
than the exclusive Monitor lock.
Namespace: System.Threading
This namespace provides all the class methods and properties required for implementation of the ReaderWriterLock class.  
Assembly: mscorlib (in mscorlib.dll)
Constructors
ReaderWriterLock: The constructor used to initialize a new 
instance of the ReaderWriterLock class.
Properties 
- 
IsReaderLockHeld: This property gets a value that points to whether the current thread holds a reader lock.
- 
IsWriterLockHeld:This property gets a value that points  to whether the current thread holds the writer lock.
- WriterSeqNum:
Gets the current sequence number.
Method
- AcquireReaderLock(Int32): Acquires a reader 
lock, using an Int32 value for the time-out.
- AcquireWriterLock(Int32): Acquires the 
writer lock, using an Int32 value for the time-out.
- ReleaseLock: Releases the lock, regardless 
of the number of times the thread acquired the lock.
- ReleaseReaderLock: 
Decrements the lock count.
- ReleaseWriterLock: 
Decrements the lock count on the writer lock.
- UpgradeToWriterLock(Int32): Upgrades a 
reader lock to the writer lock, using an Int32 value for the time-out.
- RestoreLock: Restores the lock status of 
the thread to what it was before calling ReleaseLock.
The problem with 
ReaderWriterLock is with its implementation. Several experts have slammed this 
technique and found that outside of limited scenarios, it is actually far slower 
than the Monitor.Enter method used to get an exclusive lock. 
ReaderWriterLock gives higher priority to reader threads then writers. This 
makes sense if you have many readers and only a few writers. So a lot of readers 
are able to read the resource while the writer has to wait longer to get the 
lock. But what If you have equal or more writers. The process of favoring 
readers make writer threads queue up and take a very long time to complete.
ReaderWriterLock 
intelligently handles recursive lock requests from the same thread. That is, if 
the thread calls AcquireReaderLock recursively (i.e., it already holds a reader 
lock), the lock is granted immediately and the lock count is increased. The 
thread must still call ReleaseReaderLock as many times as it called 
AcquireReaderLock. Or, it can call ReleaseLock to reduce the lock count to zero 
immediately. Be careful with ReleaseLock, though. If you subsequently call 
ReleaseWriterLock or ReleaseReaderLock, the runtime will throw an exception.
A thread can hold a reader 
lock or a writer lock, but not both at the same time. Instead of releasing a 
reader lock in order to acquire the writer lock, you can use UpgradeToWriterLock 
and DowngradeFromWriterLock.
In some situations, you might 
find that you're holding a reader lock and you need to upgrade to a writer lock. 
In that situation, call UpgradeToWriterLock, but understand that you don't get 
the writer lock immediately. Your code will have to wait for any other readers 
in the queue to release their locks, and will also have to wait behind any other 
writers that are already in the write queue.
A thread should not call 
AcquireWriterLock while it holds a reader lock. Doing so will cause the thread 
to block while it holds the reader lock, and will lead to a deadlock if you use 
an infinite timeout. You can call the IsReaderLockHeld method to determine if 
your thread currently holds a reader lock before you attempt to acquire a writer 
lock.
Note that the 
opposite — calling AcquireReaderLock whild holding a writer lock — is just fine. 
Since the thread has an exclusive lock on the resource, granting the lock is 
okay. However, if you need to know whether your thread is currently holding a 
writer lock, you can call IsWriterLockHeld.
The ReaderWriterLock class 
supports recursion; due to this it causes performance loss. in this case the class 
needs to maintain a record of the number of times each thread acquires the lock 
and increment and decrement the counter. When multiple reader threads acquire 
the same lock (remember ReaderWriterLock class allows simultaneous reads), a 
counter is maintained for each thread. This overhead is what causes the 
ReaderWriterLock to pale in comparison to the Monitor class. It is approximately 
6 times slower.
Code
In the following example we 
have three threads where the Thread 2 is a writer one while 
the Threads 1 and 3 are reader threads. When you take a look at the 
output, it's clear that the readers are granted simultaneous access to the 
initial 
variable, but when the writer thread is writing to it, all the readers wait in 
queue patiently for it to finish executing. I have made the DoWorkRead method 
parametrized in order to identify the thread on which the method is being 
executed.
using 
System;
using 
System.Threading;
namespace 
ReaderWriterLockClass
{
class akshay
    {
        int initial = 0;
        ReaderWriterLock rwl =
new ReaderWriterLock();
      public void 
myRead(object threadName)
        {
            //Accquire Reader Lock.
            rwl.AcquireReaderLock(Timeout.Infinite);
            Console.WriteLine("Read 
start: Thread: " + threadName + " " + 
initial);
            if (threadName.ToString() ==
"Thread 1")
                //Irregular sleeps makes more chances 
of
                //Multiple threads trying to 
access it
                //at same time
                Thread.Sleep(10);
            else
                Thread.Sleep(250);
            Console.WriteLine("Read 
end  : Thread: " + threadName + " " + 
initial);
            rwl.ReleaseReaderLock();
            //Release Lock
        }
        public void 
myWrite()
        {
            rwl.AcquireWriterLock(Timeout.Infinite);
            Console.WriteLine("\nWriter 
start: " + initial);
            initial++; //Writing
            Console.WriteLine("Writer 
End: " + initial);
            rwl.ReleaseWriterLock();
            Console.WriteLine();
        }
        static void 
Main(string[] args)
        {
            akshay p =
new akshay();
            for (int 
i = 0; i < 5; i++)
            {
                Thread t1 =
new Thread(p.myRead);
//Reader Thread
                //Writer Thread
                Thread t2 =
new Thread(new
ThreadStart(p.myWrite));
                //Reader Again
                Thread t3 =
new Thread(p.myRead);
                //Start all threads
                t1.Start("Thread 1");
                t2.Start();
                t3.Start("Thread 3");
                //Wait for them to finish execution
                t1.Join();
                t2.Join();
                t3.Join();
            }
            Console.Read();
       } 
    }
}
Output
A look at the output shows that once the writer 
acquires a lock, it is mutually exclusive, but both the reader threads are able 
to access the variable 
initially.
![Readerwriterlock1.gif]()
We can specify Timeout.Infinite if you really 
don't want the lock request to time out. You should be very careful with 
infinite timeout values, though. Without timeouts, a misbehaving thread that 
leaves the resource locked will cause a deadlock in your application that is 
very difficult or impossible to diagnose. At least with timeouts, you can catch 
the timeout exception and report that the resource is locked. 
It's critical that your code release any lock that 
it obtains. If a thread obtains a reader lock, then it must call 
ReleaseReaderLock to release the lock. Similarly, any call to AcquireWriterLock 
must be balanced by a call to ReleaseWriterLock. If you fail to release the 
locks, your thread will keep the resource locked and other threads will not be 
able to access it.
One more problem with the ReaderWriterLock class 
is that it allows Reader threads to acquire writer locks. If you set an infinite 
timeout, it will create a deadlock situation, where the thread just waits to get 
the Writer lock but can't because the very same thread holds on to the Reader 
lock and is yet to release it. So the application just waits and waits.
using 
System;
using 
System.Threading;
namespace 
ReaderWriterLockClass
{
class akshay
    {
        int initial = 0;
        ReaderWriterLock rwl =
new ReaderWriterLock();
      public void 
myRead(object threadName)
        {
            //Accquire Reader Lock.
            rwl.AcquireReaderLock(Timeout.Infinite);
            Console.WriteLine("Read 
start: Thread: " + threadName + " " + 
initial);
            //NEVER EVER DO THE BELOW. IT WILL CREATE 
A DEADLOCK
            rwl.AcquireWriterLock(Timeout.Infinite);
            Thread.Sleep(10);
            Console.WriteLine("Read 
start: Thread: " + threadName + " " + 
initial);
            rwl.ReleaseReaderLock();
            //Release Lock
        }
        public void 
myWrite()
        {
            rwl.AcquireWriterLock(Timeout.Infinite);
            Console.WriteLine("\nWriter 
start: " + initial);
            initial++; //Writing
            Console.WriteLine("Writer 
End: " + initial);
            rwl.ReleaseWriterLock();
            Console.WriteLine();
        }
        static void 
Main(string[] args)
        {
            akshay p =
new akshay();
            for (int 
i = 0; i < 5; i++)
            {
                Thread t1 =
new Thread(p.myRead);
//Reader Thread
                //Writer Thread
                Thread t2 =
new Thread(new
ThreadStart(p.myWrite));
                //Reader Again
                Thread t3 =
new Thread(p.myRead);
                //Start all threads
                t1.Start("Thread 1");
                t2.Start();
                t3.Start("Thread 3");
                //Wait for them to finish execution
                t1.Join();
                t2.Join();
                t3.Join();
            }
            Console.Read();
       } 
    }
}
Output
![rwl2.gif]()