tags:

views:

147

answers:

2

In C#, I have the following extremely verbose syntax for pulling a simple list of items from a database:

if (malls == null)
{
    lock (_lock)
    {
        if (malls == null)
        {
            using (var session = NhibernateHelper.OpenSession())
            {
                malls = session.CreateCriteria<Mall>()
                    .AddOrder(Order.Asc("Name")).List<Mall>();

                CacheManager.Set(CACHE_KEY, malls, TimeSpan.FromMinutes(CACHE_DURATION));
            }
        }
    }
}

I'm aware of the benefits of double checked locking and I strongly support its use, but it seems incredibly verbose. Can you recommend any syntax shortcuts or styles that might clean it up a bit?

+7  A: 

Presumably you're using double-checked locking because you have a resource which you want initialized in a lazy, threadsafe manner.

Double-checked locking is a mechanism for achieving that, but as you've correctly noted, the verbosity of the mechanism is thoroughly overwhemling the meaning of the code.

When you have a mechanism that is obscuring the meaning, hide the mechanism by creating an abstraction. One way to do that would be to create a "lazy threadsafe instantiation" class and pass a delegate to it which does the operation you would like done in a lazy, threadsafe manner.

However, there's a better way. The better way is to not do that work yourself, but rather to let a world-class expert on threading do it for you. That way you don't have to worry about getting it right. Joe Duffy has to worry about getting it right. As Joe wisely says, rather than repeating the locking mechanism all over the place, write it once and then use the abstraction.

Joe's code is here:

http://www.bluebytesoftware.com/blog/PermaLink,guid,a2787ef6-ade6-4818-846a-2b2fd8bb752b.aspx

and a variation of this code will ship in the next version of the base class library.

Eric Lippert
Awesome looking code. I'll try that, thanks!
Chris
Do MS pay people like Joe for code like that? Just interested ..
flesh
By "people like Joe", do you mean "Microsoft employees"? Yes, we pay our employees -- like Joe -- to write code. :-)
Eric Lippert
+1  A: 

To cut down on noise you can do this:

public List<Mall> Malls()
{
    EnsureMallsInitialized();
    return malls;
}

private void EnsureMallsInitialized()
{
    if (malls == null) // not set
    lock (_lock)       // get lock
    if (malls == null) // still not set
    {
        InitializeMalls();
    }        
}

private void InitializeMalls()
{
    using (var session = NhibernateHelper.OpenSession())
    {
        malls = session.CreateCriteria<Mall>()
            .AddOrder(Order.Asc("Name")).List<Mall>();

        CacheManager.Set(CACHE_KEY, malls, TimeSpan.FromMinutes(CACHE_DURATION));
    }
}
Garry Shutler