Saturday, April 16, 2011

Lazy: What it is and why you should be using it

Lazy<T> allows you to write code that not only executes on an as-needed basis, but is also guaranteed to be thread safe.  I've put together a demo application that includes a couple unit tests as well as console output to demonstrate using simple lazy initialization (which does work great for single-threaded apps) versus Lazy<T> initialization.

Basic lazy loading:
private object _obj;
public object MyObject
{
  get  {
    if (_obj == null)
      _obj = new object();
  
    return _obj;
}

Lazy<T> loading:
private Lazy<object> _obj = new Lazy<object>();
public object MyObject { get { return _obj.Value; } } //Lazy<T> guarantees that this will always return the same value

Note that this simple example is using a static initializer for _obj, I've found myself initializing Lazy<T> properties in the constructor much more often than using the static initialization, but in the spirit of a demo here we are.  In my demo solution I do indeed initialize the private Lazy<T> var in the constructor.

The basic lazy loading example above is not thread-safe, in a single threaded application it will behave just as you would expect when you look at the code, but in a multi-threaded application the MyObject property will often return different objects across threads.  This is due to the fact that multiple threads can evaluate the 'if (_obj == null)' statement prior to _obj being initialized.

The demo I put together can be found here: http://cid-edc8bd4a11230d7b.office.live.com/self.aspx/.Public/blog/LazyT.zip

No comments:

Post a Comment