Useful set of extensions and classes for simplifying and optimizing read-write synchronization with ReaderWriterLockSlim
.
There are very common but tedious patterns to follow when utilizing a ReaderWriterLockSlim
. Some of the more complex but useful patterns involve reading (with or without a read lock) and then if a condition is met, acquiring a write lock before proceeding.
This extension library removes the tediousness of properly acquiring and releasing various locks and provides easy access to timeout values if needed.
rwLockSlim.Read(() =>
{
/* do work inside a read lock */
});
using(rwLockSlim.ReadLock())
{
/* do work inside a read lock */
}
int result = rwLockSlim.Read(() =>
{
int i;
/* produce a result inside read lock */
return i;
});
rwLockSlim.Write(() =>
{
/* do work inside a read lock */
});
using(rwLockSlim.WriteLock())
{
/* do work inside a write lock */
}
int result = rwLockSlim.Write(() =>
{
int i;
/* produce a result inside write lock */
return i;
});
using(rwLockSlim.UpgradableReadLock())
{
/* do work inside an upgradable read lock */
if(condition)
{
using(rwLockSlim.WriteLock())
{
/* upgraded to a write lock */
}
}
}
These throw a TimeoutException
if a lock cannot be acquired within the time specified.
rwLockSlim.Read(1000 /* ms */, () =>
{
/* do work inside a read lock */
});
or
using(rwLockSlim.ReadLock(1000)) // ms
{
/* do work inside a read lock */
}
rwLockSlim.Write(1000 /* ms */, () =>
{
/* do work inside a write lock */
});
or
using(rwLockSlim.WriteLock(1000)) // ms
{
/* do work inside a write lock */
}
This example demonstrates how to properly query a value before writing with a 1 second timeout.
var actionWasInvoked = rwLockSlim.WriteConditional(1000 /* ms */,
() => /* condition that is queried inside an upgradable read lock */,
() => /* do work inside a write lock */);
This more advanced example optimizes the process of reading and then writing by first testing the condition within a read lock before attempting with an upgradable read lock.
int result = 0;
bool actionWasInvoked = rwLockSlim.ReadWriteConditional(ref result,
isUpgraded => /* condition that is first queried inside a read lock */,
() =>
{
int i;
/* do work inside a write lock */
return i;
});