Domanda

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?

È stato utile?

Soluzione

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...

Altri suggerimenti

From MSDN:

Some Lazy<T> constructors have a Boolean parameter named isThreadSafe that is used to specify whether the Value property will be accessed from multiple threads. If you intend to access the property from just one thread, pass in false to obtain a modest performance benefit. If you intend to access the property from multiple threads, pass in true to instruct the Lazy<T> instance to correctly handle race conditions in which one thread throws an exception at initialization time.

You wrote...

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, it has nothing to do with instance vs. static. It has to do with whether or not the value being lazy initialized will be accessed on multiple threads or not. If it will be accessed on multiple threads, use true so that Lazy<T> handles the race condition for you. If it will not be, use false so that Lazy<T> avoids taking a lock which will give you a very slight almost unnoticeable performance gain (taking uncontested locks is VERY fast).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top