Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Use ReaderWriter Lock in C#
The ReaderWriterLock class in C# provides synchronized access to a resource by allowing multiple threads to read simultaneously while ensuring exclusive access for writing operations. It offers better performance than Monitor for scenarios where reads are frequent and writes are infrequent.
Note: ReaderWriterLock is obsolete since .NET 3.5. The recommended alternative is ReaderWriterLockSlim, which provides better performance and functionality.
Syntax
Following is the syntax for declaring a ReaderWriterLock −
static ReaderWriterLock rwLock = new ReaderWriterLock();
Following is the syntax for acquiring and releasing locks −
// Acquire reader lock
rwLock.AcquireReaderLock(timeout);
try {
// Read operations
}
finally {
rwLock.ReleaseReaderLock();
}
// Acquire writer lock
rwLock.AcquireWriterLock(timeout);
try {
// Write operations
}
finally {
rwLock.ReleaseWriterLock();
}
How ReaderWriterLock Works
Properties
| Property | Description |
|---|---|
| IsReaderLockHeld | Gets a value indicating whether the current thread holds a reader lock. |
| IsWriterLockHeld | Gets a value indicating whether the current thread holds a writer lock. |
| WriterSeqNum | Gets the current sequence number that can be used to determine whether a writer lock was taken since the sequence number was obtained. |
Key Methods
| Method | Description |
|---|---|
| AcquireReaderLock(TimeSpan) | Acquires a reader lock, using a TimeSpan value for the timeout. |
| AcquireWriterLock(TimeSpan) | Acquires a writer lock, using a TimeSpan value for the timeout. |
| ReleaseReaderLock() | Decrements the lock count and releases a reader lock. |
| ReleaseWriterLock() | Decrements the lock count and releases a writer lock. |
Using ReaderWriterLock for Shared Data
Example
using System;
using System.Threading;
class SharedResource {
private static ReaderWriterLock rwLock = new ReaderWriterLock();
private static int sharedData = 0;
public static void ReadData(string threadName) {
rwLock.AcquireReaderLock(5000);
try {
Console.WriteLine($"{threadName} reading: {sharedData}");
Thread.Sleep(1000); // Simulate read operation
}
finally {
rwLock.ReleaseReaderLock();
}
}
public static void WriteData(string threadName, int value) {
rwLock.AcquireWriterLock(5000);
try {
Console.WriteLine($"{threadName} writing: {value}");
sharedData = value;
Thread.Sleep(1000); // Simulate write operation
}
finally {
rwLock.ReleaseWriterLock();
}
}
}
class Program {
public static void Main() {
Thread reader1 = new Thread(() => SharedResource.ReadData("Reader1"));
Thread reader2 = new Thread(() => SharedResource.ReadData("Reader2"));
Thread writer1 = new Thread(() => SharedResource.WriteData("Writer1", 42));
reader1.Start();
reader2.Start();
writer1.Start();
reader1.Join();
reader2.Join();
writer1.Join();
Console.WriteLine("All threads completed.");
}
}
The output of the above code is −
Reader1 reading: 0 Reader2 reading: 0 Writer1 writing: 42 All threads completed.
ReaderWriterLockSlim Alternative
Since ReaderWriterLock is obsolete, here's the recommended ReaderWriterLockSlim approach −
Example
using System;
using System.Threading;
class ModernSharedResource {
private static ReaderWriterLockSlim rwLockSlim = new ReaderWriterLockSlim();
private static int sharedValue = 100;
public static void ReadValue() {
rwLockSlim.EnterReadLock();
try {
Console.WriteLine($"Current value: {sharedValue}");
}
finally {
rwLockSlim.ExitReadLock();
}
}
public static void WriteValue(int newValue) {
rwLockSlim.EnterWriteLock();
try {
Console.WriteLine($"Updating value to: {newValue}");
sharedValue = newValue;
}
finally {
rwLockSlim.ExitWriteLock();
}
}
}
class Program {
public static void Main() {
ModernSharedResource.ReadValue();
ModernSharedResource.WriteValue(200);
ModernSharedResource.ReadValue();
Console.WriteLine("ReaderWriterLockSlim example completed.");
}
}
The output of the above code is −
Current value: 100 Updating value to: 200 Current value: 200 ReaderWriterLockSlim example completed.
Comparison
| ReaderWriterLock | ReaderWriterLockSlim |
|---|---|
| Obsolete since .NET 3.5 | Recommended for new development |
| Higher memory overhead | Lower memory footprint |
| Supports recursion by default | Recursion must be explicitly enabled |
| AcquireReaderLock() / ReleaseReaderLock() | EnterReadLock() / ExitReadLock() |
Conclusion
ReaderWriterLock provides synchronized access allowing multiple concurrent readers while ensuring exclusive writer access. However, it's obsolete and should be replaced with ReaderWriterLockSlim for better performance and modern .NET development practices.
