在初始化期间使用Lazy<T>
类和标记isThreadSafe: false
有什么含义?
在懒惰需要访问实例成员而不是在类构造函数中初始化lazy的静态成员的情况下,这会在所有用法中自动需要isThreadSafe: false
吗?
答案 0 :(得分:5)
在懒惰需要访问实例成员而不是在类构造函数中初始化lazy的静态成员的情况下,这会在所有用法中自动要求isThreadSafe:false吗?
否 - isThreadSafe
参数仅影响Lazy<T>
中的值的创建方式。
基本上,当您将其设置为false时,创建值的方法只会创建值,将其设置为内部存储,然后返回值。
如果将其设置为true,则创建将包含在lock
内,从而阻止多个线程创建对象。这映射到LazyThreadSafetyMode.ExecutionAndPublication。
您还可以明确指定PublicationOnly
,这将允许创建多个值,但在内部使用Interlocked.CompareExchange而不是锁定,以确保第一个完成的创建例程的值是用于对象的那个。
请注意,这些选项都不会对使用哪些成员计算值产生任何影响 - 它们只影响值本身的创建方式。除了创建之外的所有内容的访问始终是线程安全的。如果您在类构造函数中初始化Lazy<T>
实例成员,则可以有效地保证不需要同步,因此您可以将isThreadSafe
设置为false - 但这也意味着在这种情况下绝对没有理由使用Lazy<T>
,因为你正在使用显式实例化......
答案 1 :(得分:2)
来自MSDN:
某些
Lazy<T>
构造函数具有名为Boolean
的{{1}}参数,用于指定是否将从多个线程访问isThreadSafe
属性。 如果您打算只从一个线程访问该属性,请传入Value
以获得适度的性能优势。如果您打算从多个线程访问该属性,请传入false
以指示true
实例正确处理一个线程在初始化时抛出异常的竞争条件。
你写了......
在懒惰需要访问实例成员而不是在类构造函数中初始化lazy的静态成员的情况下,这会在所有用法中自动要求isThreadSafe:false吗?
不,它与实例与静态无关。它与是否在多个线程上访问初始化延迟的值有关。如果将在多个线程上访问它,请使用Lazy<T>
以便true
为您处理竞争条件。如果不是,请使用Lazy<T>
以便false
避免锁定,这会给你带来非常轻微的几乎无法察觉的性能提升(采取无争议的锁定非常快)。