懒惰<t>与LazyThreadSafetyMode.None可以抛出NullReferenceException </t>

时间:2014-02-09 11:08:40

标签: c# .net multithreading lazy-evaluation

我定义了以下Lazy<Y>

var preinitializedValue = new X();

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

稍后可以从多个线程访问Lazy<T>.Value。在启动应用程序后,随机时间Value无法初始化并中断AppDomain的其余部分。只有重启才能解决问题。抛出以下异常:

  

ValueFactory尝试访问此实例的Value属性。

此异常似乎缓存为described here

经过调查,根本问题似乎是原始错误是NullReferenceException

  

对象引用未设置为对象的实例。   (的NullReferenceException)

这里发生了什么?为什么Lazy<T>会随机抛出NullReferenceException

1 个答案:

答案 0 :(得分:3)

这有时会失败的原因是因为LazyThreadSafetyMode.None在通过多个线程访问时不提供任何关于正确性的保证。 LazyThreadSafetyMode.None状态的documentation

  

Lazy实例不是线程安全的;如果访问实例   从多个线程,它的行为是未定义的。仅使用此模式   当高性能至关重要且Lazy实例是   保证永远不会从多个线程初始化。

您错误地认为,因为您的委托总是返回相同的值,所以不需要线程安全,但事实并非如此。

您应该使用Lazy<T>PublicationOnly初始化ExecutionAndPublication