4

在初始化期间使用Lazy<T>类和标记有什么含义?isThreadSafe: false

在惰性需要访问实例成员而不是静态成员的情况下,其中惰性在类构造函数中初始化,这是否isThreadSafe: false 在所有用法中都自动需要?

4

2 回答 2

5

在惰性需要访问实例成员而不是静态成员的情况下,其中惰性在类构造函数中初始化,这是否会自动要求 isThreadSafe: false 在所有用法中?

否 - 该isThreadSafe参数仅影响 中的值的Lazy<T>创建方式。

基本上,当您将其设置为 false 时,创建值的方法只会创建值,将其设置到内部存储,然后返回值。

如果将其设置为 true,则创建将被包裹在 alock中,从而防止多个线程创建对象。这映射到LazyThreadSafetyMode.ExecutionAndPublication

您还可以PublicationOnly显式指定,这将允许创建多个值,然后在内部使用Interlocked.CompareExchange而不是锁来确保第一个完成的创建例程的值是用于对象的值。

请注意,这些选项都不会影响用于计算值的成员 - 它们只会影响值本身的创建方式。对除创建之外的所有内容的访问始终是线程安全的。如果您在类构造函数中初始化Lazy<T> 实例成员,则有效地保证不需要同步,因此您可以设置isThreadSafe为 false - 但这也意味着绝对没有理由Lazy<T>在这种情况下使用,因为您使用的是显式实例化...

于 2012-03-26T17:41:13.437 回答
2

来自MSDN

一些Lazy<T>构造函数有一个Boolean名为的参数isThreadSafe,用于指定是否Value从多个线程访问该属性。如果您打算仅从一个线程访问该属性,请传入false以获得适度的性能优势。如果您打算从多个线程访问该属性,请传入true以指示Lazy<T>实例正确处理一个线程在初始化时引发异常的竞争条件。

你写了...

在惰性需要访问实例成员而不是静态成员的情况下,其中惰性在类构造函数中初始化,这是否会自动要求 isThreadSafe: false 在所有用法中?

不,它与实例与静态无关。它与是否会在多个线程上访问延迟初始化的值有关。如果它将在多个线程上访问,请使用true以便Lazy<T>为您处理竞争条件。如果不是,请使用falseLazy<T>避免获取锁,这会给您带来非常轻微的几乎不明显的性能提升(获取无竞争的锁非常快)。

于 2012-03-26T17:41:16.317 回答