Click here to Skip to main content
15,867,878 members
Articles / General Programming / Threads
Tip/Trick

ReaderWriterLockSlim Extensions

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
13 Feb 2013CPOL 9.8K   95   4  
Make your synchronizion easier by using Read/Write extensions.

Introduction

I'm guessing plenty of people have already done this themselves.  But if you haven't written Read/Write extensions for ReadWriterLockSlim (or any other lock class), here you go.

Background 

 I found myself writing the following pattern way too often: 

bool lockHeld = false;
try
{
    lockHeld = rwlock.EnterReadLock();
    closure();
}
finally
{
    if (lockHeld)
        rwlock.ExitReadLock();
}	

 I  also found myself needing a way to enter locks with timeouts in the same way.  So I started by making the following extension:

public static bool EnterReadLock(this ReaderWriterLockSlim target,
    int? millisecondsTimeout, bool throwsOnTimeout = false)
{
    if (millisecondsTimeout == null)
        target.EnterReadLock();
    else if (!target.TryEnterReadLock(millisecondsTimeout.Value))
    {
        if (throwsOnTimeout)
            throw new TimeoutException(
                "Could not gain a read lock within the timeout specified. " +
                "(millisecondsTimeout=" + millisecondsTimeout.Value + ") ");

        return false;
    }

    return true;
} 

Which led me to write a set of extensions that look like this:

public static bool Read(this ReaderWriterLockSlim target,
    Action closure, int? millisecondsTimeout = null, bool throwsOnTimeout = false)
{
    Contract.Requires<ArgumentNullException>(closure != null);
    Contract.Requires<ArgumentOutOfRangeException>(
        millisecondsTimeout == null || millisecondsTimeout >= 0
    );

    bool lockHeld = false;
    try
    {
        lockHeld = target.EnterReadLock(millisecondsTimeout, throwsOnTimeout);
        closure();
    }
    finally
    {
        if (lockHeld)
            target.ExitReadLock();
    }

    return lockHeld;
}

Resulting in some very flexible and robust delegated extensions.

Usage Examples

Can't be much easier than:
C++
rwlock.Read( ()=> { /* Some read operation */ } ); 
C++
if( !rwlock.Read( ()=> { /* Some read operation */ }, 1000 ) )
{ // Was unable to get a read lock within 1 second?
  /* Do something else */
}
C++
int myValue = rwlock.ReadValue( ()=>
{
  int value;
  /* Get the value */
  return value;
} );
C++
rwlock.ReadUpgradable( ()=>
{
    if(needsWrite()) { // Do verification before writing...
         rwlock.Write(()=>{
             /* Do write operation */
         }
    }
}

Download the code for more useful extensions.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
Just a crazy developer with crazy ideas of grandure.

What's that? Anal probe? NO, I said "Anal CODE!" Get that thing away, and get back to EditPlus.

Comments and Discussions

 
-- There are no messages in this forum --