Question

Recently I was having some issues with a singelton class that was lazy initializing a dictionary where a second thread would try to use it before it had actually been populated. So I implemented the variable initialization through the Lazy<T> class.

Here is my code:

private static Dictionary<string, string> GroupDefaults
{
    get { return mGroupDefaults.Value; }
}
private static Lazy<Dictionary<string, string>> mGroupDefaults =
    new Lazy<Dictionary<string,string>>(delegate
    {
        Dictionary<string, string> defaults = new Dictionary<string, string>();
        foreach (KeyValuePair<string, UnitGroup> groupDef in Groups)
            defaults.Add(groupDef.Key, groupDef.Value.First().Key);
        return defaults;
    });

This fixed the problem and now I am considering making this a regular practice of mine to use the Lazy<T> class anywhere I do lazy initialization to avoid any possible threading issues. So basically I would like to know if this is good/common practice? Or will it be detremental to performance or something?

Was it helpful?

Solution

It's pretty hard to say without knowing what type of performance constraints you have, but in my experience, one-time initialization is rarely a bottleneck (since by definition it only occurs once.) Lazy<T> was written to provide you with this exact service, so I would recommend using it.

OTHER TIPS

From the documentation, I find the following:

If no delegate is passed in the Lazy constructor, the wrapped type is created by using Activator.CreateInstance when the value property is first accessed. If the type does not have a default constructor, a run-time exception is thrown.

Activator.CreateInstance is a method that is notoriously bad for performance. However, that doesn't seem to be a problem in your case, and at any rate, as dlev said, invoking the method once wouldn't be a problem. I haven't seen Lazy<T> used very often, but I do not see any reason not to use it in your case.

If this is for a singleton, a static constructor might be what you want. Something like:

class MySingleton
{
    static MySingleton()
    {
         Instance().InitDict();
    }
}

I think you may be using Lazy for not it's intended use. Lazy is to be used for situations where something has a large initialization cost, but there is a probable chance that it may not be used during the lifetime of the object.

If you always call GroupDefaults at least once per it's lifetime a better method would be to initialize GroupDefaults in a background thread at the start of the container's lifetime and hope that it is done before it is done initializing (I know there is a class for this but I need to dig in to the MSDN to find it)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top