Pergunta

I defined the following Lazy<Y>:

var preinitializedValue = new X();

this.lazy = new Lazy<X>(() => preinitializedValue, LazyThreadSafetyMode.None);

Later on the Lazy<T>.Value is accessed from multiple threads. After starting the application, at random times the Value fails to initialize and breaks for the remainder of the AppDomain. Only a restart solves the problem. The following exception is thrown:

ValueFactory attempted to access the Value property of this instance.

This exception seems to be a cached as described here.

After investigating, the root problem seems to be that the originating error is a NullReferenceException:

Object reference not set to an instance of an object. (NullReferenceException)

What is going on here? Why does the Lazy<T> throw a NullReferenceException at random times.

Foi útil?

Solução

The reason this sometimes fails is because LazyThreadSafetyMode.None doesn't give any guarantees about correctness when accessed over multiple threads. The documentation for LazyThreadSafetyMode.None states:

The Lazy instance is not thread safe; if the instance is accessed from multiple threads, its behavior is undefined. Use this mode only when high performance is crucial and the Lazy instance is guaranteed never to be initialized from more than one thread.

You incorrectly assumed that since your delegate always returned the same value, no thread-safety was needed, but this isn't the case.

You should initialize the Lazy<T> with either PublicationOnly or ExecutionAndPublication.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top