LazyThreadSafetyMode 枚举

定义

指定 Lazy<T> 实例如何同步多个线程间的访问。

public enum class LazyThreadSafetyMode
public enum LazyThreadSafetyMode
type LazyThreadSafetyMode = 
Public Enum LazyThreadSafetyMode
继承
LazyThreadSafetyMode

字段

ExecutionAndPublication 2

使用锁来确保只有一个线程可以在线程安全的方式下初始化 Lazy<T> 实例。 实际上,初始化方法以线程安全的方式执行, (字段名称) 中称为 ExecutionPublication 的 初始化值也是线程安全的,从某种意义上说,只有一个值可供所有线程发布和使用。 如果初始化方法(如果没有初始化方法,则为无参数构造函数)在内部使用锁,则可能会发生死锁。 如果使用指定初始化方法(valueFactory 参数)的 Lazy<T> 构造函数,并且如果此初始化方法在你首次调用 Value 属性时引发异常(或无法处理异常),则会缓存该异常并在随后调用 Value 属性时再次引发该异常。 如果使用不指定初始化方法的 Lazy<T> 构造函数,则不会缓存 T 无参数构造函数引发的异常。 在此情况下,对 Value 属性进行后续调用可成功初始化 Lazy<T> 实例。 如果初始化方法递归访问 Lazy<T> 实例的 Value 属性,则引发 InvalidOperationException

None 0

Lazy<T> 实例不是线程安全的;如果从多个线程访问该实例,则其行为不确定。 仅应在高性能至关重要并且保证决不会从多个线程初始化 Lazy<T> 实例时才使用该模式。 如果使用指定初始化方法(valueFactory 参数)的 Lazy<T> 构造函数,并且如果此初始化方法在你首次调用 Value 属性时引发异常(或无法处理异常),则会缓存该异常并在随后调用 Value 属性时再次引发该异常。 如果使用不指定初始化方法的 Lazy<T> 构造函数,则不会缓存 T 无参数构造函数引发的异常。 在此情况下,对 Value 属性进行后续调用可成功初始化 Lazy<T> 实例。 如果初始化方法递归访问 Lazy<T> 实例的 Value 属性,则引发 InvalidOperationException

PublicationOnly 1

当多个线程尝试同时初始化一个 Lazy<T> 实例时,允许所有线程都运行初始化方法(如果没有初始化方法,则运行无参数构造函数)。 完成初始化的第一个线程设置 Lazy<T> 实例的值。 这在字段名称中称为 Publication 。 该值将返回给同时运行初始化方法的其他所有线程,除非初始化方法对这些线程引发异常。 争用线程创建的任何 T 实例都将被放弃。 实际上,初始化值的发布是线程安全的,从某种意义上说,只有一个初始化的值可以发布和使用所有线程。 如果初始化方法对任何线程引发异常,则该异常会从该线程上的 Value 属性传播出去。 不缓存该异常。 IsValueCreated 属性的值仍然为 false,并且随后通过其中引发异常的线程或通过其他线程对 Value 属性的调用会导致初始化方法再次运行。 如果初始化方法递归访问 Value 实例的 Lazy<T> 属性,则不会引发异常。

注解

使用此枚举指定 mode 构造函数的参数 Lazy<T> 。 所有构造函数对线程同步的影响都可以通过此枚举来描述,无论它们是否具有 mode 参数。

Lazy<T>实例由用户指定的初始化方法或由 的无参数构造函数初始化T。 初始化方法由 valueFactory 构造函数的 Lazy<T> 参数指定。 方法返回 的 T实例,该实例是 由 实例延迟实例化的类型 Lazy<T>。 如果构造函数没有 valueFactory 参数,则 使用 的 T 无参数构造函数初始化 Lazy<T> 实例。 在任一情况下,初始化都发生在首次调用 Lazy<T>.Value 属性时。

除了指定实例的 Lazy<T> 线程安全外,此枚举还影响异常缓存。 为 Lazy<T> 实例缓存异常时,只能获得一次初始化实例的机会。 如果在首次调用 Lazy<T>.Value 属性时引发异常,则会缓存该异常,并在对属性的所有后续调用 Lazy<T>.Value 中重新引发。 缓存异常的优点是,即使发生错误,任何两个线程也始终获得相同的结果。

指定 PublicationOnly 模式时,永远不会缓存异常。 指定 None 或 ExecutionAndPublication 时,缓存取决于是指定初始化方法还是允许使用 无 T 参数构造函数。 指定初始化方法可启用这两种模式的异常缓存。 初始化方法非常简单。 例如,它可能会调用 T 的无参数构造函数:C# 中的 new Lazy<Contents>(() => new Contents(), mode) 或 Visual Basic 中的 New Lazy(Of Contents)(Function() New Contents())。 如果使用的构造函数未指定初始化方法,则不会缓存由 无参数构造函数引发的 T 异常。 下表汇总了异常缓存行为。

模式 使用初始化方法 对 使用无参数构造函数 T
Cached(缓存的请求) 未缓存
PublicationOnly 未缓存 未缓存
ExecutionAndPublication Cached(缓存的请求) 未缓存

适用于

另请参阅