Click here to Skip to main content
Click here to Skip to main content
Go to top

ReaderWriterLockSlim Extensions

, 13 Feb 2013
Rate this:
Please Sign up or sign in to vote.
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:
rwlock.Read( ()=> { /* Some read operation */ } ); 
if( !rwlock.Read( ()=> { /* Some read operation */ }, 1000 ) )
{ // Was unable to get a read lock within 1 second?
  /* Do something else */
}
int myValue = rwlock.ReadValue( ()=>
{
  int value;
  /* Get the value */
  return value;
} );
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)

Share

About the Author

essence
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 --
| Advertise | Privacy | Mobile
Web02 | 2.8.140905.1 | Last Updated 14 Feb 2013
Article Copyright 2013 by essence
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid