Making use of lazy initialization in .Net 4

One of the most lesser known, yet very cool, additions since .Net 4.0 is the generic Lazy<T> class. It allows you to defer the initialization of a type until it’s needed.

What is it?

Lazy<T> is a generic class introduce in .Net 4.5 which acts as factory for the wrapped object constructing it only once .Value is called on it. At this point, the constructor for your object is called. It is by default thread-safe but you can change that behavior if desired.

How do I use it?

The simplest way is to call the default constructor like so:

var myLazyObject = new Lazy<MyLazyObject>();

Lazy<T> has a few constructors but they all offer various combinations which effectively revolve around two concepts : do you want a thread-safe version of Lazy<T>? AND do you want to select a particular constructor for your wrapped object?

Thread-Safety

The default constructor of Lazy<T>() is thread-safe. This means that the object can be initialized in any thread and it’ll be available to other threads without any additional effort.

More specifically, the default constructor uses the ExecutionAndPublication thread-safe mode which means that the thread initializing the object will lock it to make sure that it’s only done once by that one thread.

In contrast, you may use the Lazy<T>(Boolean) constructor with a value of true to also initialize it with thread-safety on but in this case the threads will compete for the initialization of the object and race conditions will apply.

Lastly, you can pass false to the Lazy<T>(Boolean) constructor if you don’t want it to be thread-safe.

IMPORTANT: Thread-safety relates to access to the Lazy<T> object wrapper, not to the object you are wrapping inside it! There's a big difference! If you are going to be using the object in a multi-threading scenario, you still have to make sure that your custom object is thread-safe too.

Wrapped Object Constructor Selection

If you need to initialized your object using any specific constructor overloads then you can use the following constructor:

Lazy<T>(Func<T>)

This takes a delegate which should match one of your constructor overloads and gives you a chance to pass data in.

You can also call Lazy<T>(Func<T>,Boolean) to set the right constructor and choose your thread-safety at the same time.

When should I use it?

There are many scenarios that can benefit from this.

You may, for instance, have a very large object that is not always needed in every program execution, or you may be doing mobile development and you have objects that are only needed when the app is inactive in the background.

Whatever the reason, you just gotta keep in mind what the pattern does : not create the object until it is accessed.

Why not always use it?

Low Latency

Most low latency patterns generally revolve around the idea of initializing objects ahead of use and caching them for fast read access. Using lazy initialization in this case would be highly inappropriate since it would result in the complete opposite of the architectural goal we are trying to achieve.

Overhead

Particularly when choosing the thread-safe option for Lazy<T>, there is always going to be extra overhead to make that happen, so newing up your objects the standard way should, as a general rule, always be faster.

Having said that just out of curiosity, I did some simple benchmarking using a console app and verified that the difference varies from nothing to 1 extra millisecond. Still there is no guarantee that the performance may not degrade with larger memory footprints or other runtime variables.

Conclusion

Lazy<T> is a available from .Net 4.5+ and is a great way of deferring construction of objects that may be infrequently used in your application or/and are expensive to construct. This can be particularly useful in mobile apps where you always want to make sure your memory footprint is as small as possible at all times.

More info on MSDN : https://msdn.microsoft.com/en-us/library/dd642331(v=vs.110).aspx

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s