Search code examples
.netgenericsthread-safetylazy-evaluationbase-class-library

Implications of Lazy<T> and threadsafe false


What are the implications of the using the Lazy<T> class and marking isThreadSafe: false during initialization?

In a scenario where lazy needs to access instance members and not static members where the lazy is initialized inside the class constructor does this automatically require isThreadSafe: false in all usages?


Solution

  • In a scenario where lazy needs to access instance members and not static members where the lazy is initialized inside the class constructor does this automatically require isThreadSafe: false in all usages?

    No - The isThreadSafe argument only affects how the value within the Lazy<T> is created.

    Basically, when you set it to false, the method to create the value will just create the value, set it to the internal storage, and return the value.

    If you set it to true, then the creation will be wrapped inside of a lock, preventing more than one thread from ever creating the object. This maps to LazyThreadSafetyMode.ExecutionAndPublication.

    You can also specify PublicationOnly explicitly, which will allow more than one value to be created, but then use an Interlocked.CompareExchange internally instead of a lock to make sure that the first completed creation routine's value is the one that's used for the object.

    Note that none of these options has any affect at all on which members are used for computing the value - they only affect how the value itself is created. The access for everything other than creation is always thread safe. If you're initializing a Lazy<T> instance member within a class constructor, you're effectively guaranteeing that there will be no synchronization required, so you could set isThreadSafe to false - but that would also mean that there is absolutely no reason to use Lazy<T> in this situation, since you're using explicit instantiation...