Lazy<T> is new in the .NET 4.0 Framework and is more of a helper class for handling multi-threaded access to shared resources that are expensive to create. To keep from creating these shared resources multiple times, one often did some sort of double-check locking to see if the resource was already being created by one thread before having another thread attempt to create it again.
Let's take the example of a Database Class that has a shared resource of all databases on the network. Let's assume getting the list of databases on the network is or could be a very expensive operation and we only want to do this once.
Double-Check Locking
To synchronize access to this shared resource and make sure the databases are only discovered once, we will handle resource synchronization with double-check locking the ol' fashioned way:
public class Database
{
private static DatabaseCollection _databasesOnNetwork;
private static Object _sync = new object();
public DatabaseCollection DatabasesOnNetwork
{
get
{
// Double-Check Locking
if (_databasesOnNetwork == null)
{
lock (_sync)
{
if (_databasesOnNetwork == null)
_databasesOnNetwork = GetListOfDatabasesOnNetwork();
}
}
return _databasesOnNetwork;
}
}
private static DatabaseCollection GetListOfDatabasesOnNetwork()
{
// An Obvious Simplification
return new DatabaseCollection();
}
}
public class DatabaseCollection { }
This works pretty well and makes sure GetListOfDatabasesOnNetwork() is called only once.
Lazy<T> in .NET 4.0 Framework
Lazy<T> will handle this for us with much less code. By default, Lazy<T> is thread-safe unless you turn it off. We can rewrite the code above as follows using Lazy<T>. Notice I am passing in a Function<T> as part of the Lazy<T> Constructor to tell it how to create the DatabaseCollection.
public class Database
{
private Lazy<DatabaseCollection> _databasesOnNetwork
= new Lazy<DatabaseCollection>(() => GetListOfDatabasesOnNetwork());
public DatabaseCollection DatabasesOnNetwork
{
get
{
return _databasesOnNetwork.Value;
}
}
private static DatabaseCollection GetListOfDatabasesOnNetwork()
{
// An Obvious Simplification
return new DatabaseCollection();
}
}
public class DatabaseCollection { }
Notice all of that ugly double-check locking code is gone, gone, gone! It is now encapsulated inside the Lazy<T> Class.
You can check out some other recent tutorials on C# 4.0:

Comments