Wednesday, December 25, 2013

"Using" Statements with Proxies

Summary

Every software developer who is doing more than simply churning out keywords and semicolons strives to create maintainable code.  In an effort to do so, we all have to take a step back and make decisions on how to handle certain complexities.  A common design that I find to be sloppy, is the try-finally statement.  I find that it does not grow well.

I think that examples do well to explain... Here, we're going to use a ReaderWriterLock.  This object in particular interests me, because it lacks a keyword that a normal lock enjoys (i.e. lock).

Normal way to use a ReaderWriterLock

var reader = new System.Threading.ReaderWriterLock();

try
{
  reader.AcquireWriterLock(TimeSpan.FromSeconds(1));

  // Do Work...
  // Blah blah blah
  // Foos and bars all over the place...
}
finally
{
  reader.ReleaseReaderLock();
}


While this works as expected, I find it hideous.  We have to instantiate the lock in a different scope than we use it and the ReleaseReaderLock() method has to be called in different scope than the AcquireWriterLock().  It just doesn't flow...

Nice to have...

Wouldn't it be nice if we were provided something like the lock keyword.  Then we could write something like the following:

var reader = new System.Threading.ReaderWriterLock();

lockReader(reader, TimeSpan.FromSeconds(1))
{
  // Do Work...
  // Blah blah blah
  // Foos and bars all over the place...
}


Way more concise!  Alas, no such beast exists.  So, why don't we create our own version!

Concise = Proxy + "Using" Statement

While we don't have a lockReader keyword available, we do have using.  So, I propose we create a wrapper class for the ReaderWriterLock that outputs a proxy whenever you acquire a reader or writer lock.  The proxy class will inherit IDisposable and the Dispose() method will release the lock. Simple enough?

Now, for some code:

First, the proxy class:

public class RWLockProxy : IDisposable
{
  private bool _readLock;
  private ReaderWriterLock _rwLock;

  private RWLockProxy()
  {
  }

  public static RWLockProxy AcquireReader(ReaderWriterLock rwLock, TimeSpan timeout)
  {
    rwLock.AcquireReaderLock(timeout);
    return new RWLockProxy { _rwLock = rwLock, _readLock = true };
  }

  public static RWLockProxy AcquireWriter(ReaderWriterLock rwLock, TimeSpan timeout)
  {
    rwLock.AcquireWriterLock(timeout);
    return new RWLockProxy { _rwLock = rwLock, _readLock = false };
  }

  public void Dispose()
  {
    if (_readLock)
      _rwLock.ReleaseReaderLock();
    else
      _rwLock.ReleaseWriterLock();
  }
}


Nothing too complicated here... Notice that I put all the ReaderWriterLock logic inside the proxy class.  I do this to keep everything together and to not spread logic out across multiple classes.  I find that it is easier to read and maintain.

Now for the wrapper class:

public class RWLock
{
  private readonly ReaderWriterLock _lock = new ReaderWriterLock();

  public RWLockProxy AcquireReader(TimeSpan timeout)
  {
    return RWLockProxy.AcquireReader(_lock, timeout);
  }

  public RWLockProxy AcquireWriter(TimeSpan timeout)
  {
    return RWLockProxy.AcquireWriter(_lock, timeout);
  }
}


Event simpler than the proxy!  Notice that we don't even provide the option to release the lock.  The proxy takes care of it.

And finally, here is the code using it:

var reader = new RWLock();

using(reader.AcquireReader(TimeSpan.FromSeconds(1)))
{
  // Do Work...
  // Blah blah blah
  // Foos and bars all over the place...
}


Just as concise as our non-existent lockReader!  Notice that we don't even care about the name of the proxy object.  We just let the using statement take it and dispose of it when we leave the scope.

Conclusion

So there you have it... in a nutshell, we have used a proxy class, a wrapper class and the using statement to create something very similar to the lock statement for the ReaderWriterLock and completely avoid a try-finally statement.  The code is easy to read, and should be easier to maintain.

Saturday, December 21, 2013

About Me

Who am i...

I am a Software Engineer at Lockheed Martin Missiles and Fire Control.  I am the software lead for the Telemetry group.  I have a beautiful wife and two small boys who all inspire me. 


Schooling

I received my BS of Electrical Engineering from the University of Oklahoma (OU).  (Which was the last time I did anything that resembled Electrical Engineering...)  I am now starting my MS of Software Engineering at Southern Methodist University (SMU).


Software Upbringing

Throughout my career I have gone through the normal paradigm progression:
  • Imperative Programming in C.
  • Grew to appreciate library development with Object Oriented Programming in C++.
  • The desktop application world lead me to WinForms/WPF and C#.
  • And now I am dabbling in the elegance of functional programming with F# and Haskell.

Software Fervor

I am jubilant to build a data structure for a complex problem.  Excited to convert a synchronous process to a streamlined asynchronous system.  And fulfilled to find a benchmark that matches my predictions.

This blog will center around C# and my different ideas and design structures.  I encourage everyone to love and hate my ideas.  With everything, I do this hoping to learn.  If I present something that is misguided, inaccurate, or just plain wrong... then don't hesitate to say so!


Where else online...

You can find/contact me on LinkedIn and StackOverflow.  I try to stay active on both.  And if you're interested, I have an online resume out there as well.