For the background story of this code, check my blog.
The purpose is to demonstrate an approach of using extension methods in combination with delegates and anonymous methods to hide repetitive code structures, which allows you to remove some "noise" from the code, making it more succinct.
In short, the longer code below is a class with extension methods for the
ReaderWriterLockSlim class, allowing you to write relatively compact code for executing code under different locks, while still doing it in a safe manner that will exit the locks in case of exceptions and such. Example usage of the extension
methods:
private static int GetFromQueueWithExtensions()
{
int result = -1;
_lock.RunWithUpgradeableReadLock(() =>
{
if (sharedResource.Count > 0)
{
_lock.RunWithWriteLock(() =>
{
result = sharedResource.Dequeue();
});
}
});
return result;
}
And the full class with extension methods follows below. OK, perhaps a bit on the long side but hey, it's documented :)
public static class ReaderWriterLockSlimExtensions
{
/// <summary>
/// Runs the given action under a read lock
/// </summary>
/// <param name="readerWriterLock">The <see cref="ReaderWriterLock"/> to use for locking.</param>
/// <param name="action">The <see cref="Action"/> to peform</param>
/// <param name="millisecondsTimeout">The timeout in milliseconds.</param>
/// <remarks>If <paramref name="millisecondsTimeout"/> is -1, the method will wait infinitely for acquiring the lock.</remarks>
public static void RunWithReadLock(this ReaderWriterLockSlim readerWriterLock, Action action, int millisecondsTimeout)
{
if (readerWriterLock.TryEnterReadLock(millisecondsTimeout))
{
try
{
action();
}
finally
{
readerWriterLock.ExitReadLock();
}
}
}
/// <summary>
/// Runs the given code under a read lock.
/// </summary>
/// <param name="readerWriterLock">The <see cref="ReaderWriterLock"/> to use for locking.</param>
/// <param name="action">The <see cref="Action"/> to peform</param>
public static void RunWithReadLock(this ReaderWriterLockSlim readerWriterLock, Action action)
{
RunWithReadLock(readerWriterLock, action, -1);
}
/// <summary>
/// Runs the given code under an upgradeable read lock.
/// </summary>
/// <param name="readerWriterLock">The <see cref="ReaderWriterLock"/> to use for locking.</param>
/// <param name="action">The <see cref="Action"/> to peform</param>
/// <param name="millisecondsTimeout">The timeout in milliseconds.</param>
/// <remarks>If <paramref name="millisecondsTimeout"/> is -1, the method will wait infinitely for acquiring the lock.</remarks>
public static void RunWithUpgradeableReadLock(this ReaderWriterLockSlim readerWriterLock, Action action, int millisecondsTimeout)
{
if (readerWriterLock.TryEnterUpgradeableReadLock(millisecondsTimeout))
{
try
{
action();
}
finally
{
readerWriterLock.ExitUpgradeableReadLock();
}
}
}
/// <summary>
/// Runs the given code under an upgradeable read lock.
/// </summary>
/// <param name="readerWriterLock">The <see cref="ReaderWriterLock"/> to use for locking.</param>
/// <param name="action">The <see cref="Action"/> to peform</param>
public static void RunWithUpgradeableReadLock(this ReaderWriterLockSlim readerWriterLock, Action action)
{
RunWithUpgradeableReadLock(readerWriterLock, action, -1);
}
/// <summary>
/// Runs the given code under a write lock.
/// </summary>
/// <param name="readerWriterLock">The <see cref="ReaderWriterLock"/> to use for locking.</param>
/// <param name="action">The <see cref="Action"/> to peform</param>
/// <param name="millisecondsTimeout">The timeout in milliseconds.</param>
/// <remarks>If <paramref name="millisecondsTimeout"/> is -1, the method will wait infinitely for acquiring the lock.</remarks>
public static void RunWithWriteLock(this ReaderWriterLockSlim readerWriterLock, Action action, int millisecondsTimeout)
{
if (readerWriterLock.TryEnterWriteLock(millisecondsTimeout))
{
try
{
action();
}
finally
{
readerWriterLock.ExitWriteLock();
}
}
}
/// <summary>
/// Runs the given code under a write lock.
/// </summary>
/// <param name="readerWriterLock">The <see cref="ReaderWriterLock"/> to use for locking.</param>
/// <param name="action">The <see cref="Action"/> to peform</param>
public static void RunWithWriteLock(this ReaderWriterLockSlim readerWriterLock, Action action)
{
RunWithWriteLock(readerWriterLock, action, -1);
}
}
Fork
1 Feedback
You must log in before you can give any feedback
0
I'm a big fan of using Extension methods, can create clean code, but can make it hard to debug.
0
I don't think extension methods are very hard to understand or debug. They are just like regular methods in my opinion.
However lamba expressions are something that many developers, especially beginners, have a hard time debugging since it breaks the usual linear flow of the code. In spite of that I still love them :)
You must log in before you can post a comment


839
0


Mark '.net' tag as 'like'
Mark '.net' tag as 'ignore'