导出 (0) 打印
全部展开
信息
您所需的主题如下所示。但此主题未包含在此库中。

LazyThreadSafetyMode 枚举

2013/12/13

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

Namespace:  System.Threading
程序集:  mscorlib(位于 mscorlib.dll 中)

public enum LazyThreadSafetyMode

成员名称说明
ExecutionAndPublication使用锁来确保只有一个线程可以在线程安全的方式下初始化 Lazy<T> 实例。如果初始化方法(如果没有初始化方法,则为默认构造函数)在内部使用锁,则可能会发生死锁。如果您使用指定初始化方法(valueFactory 参数的 Lazy<T> 构造函数,并且如果首次调用 Lazy<T>.Value 属性时,该初始化方法引发异常(或者无法处理异常),则该异常将在 Lazy<T>.Value 属性的后续调用上再次缓存和引发该异常。如果您使用不指定初始化方法的 Lazy<T> 构造函数,则不会缓存 T 默认构造函数引发的异常。在这种情况下,随后调用 Lazy<T>.Value 属性可能会成功地初始化 Lazy<T> 实例。如果初始化方法递归访问 Lazy<T> 实例的 Value 属性,则引发 InvalidOperationException
NoneLazy<T> 实例不是线程安全的;如果从多个线程访问该实例,则其行为不确定。仅应在高性能至关重要并且保证决不会从多个线程初始化 Lazy<T> 实例时才使用该模式。如果您使用指定初始化方法(valueFactory 参数的 Lazy<T> 构造函数,并且如果首次调用 Lazy<T>.Value 属性时,该初始化方法引发异常(或者无法处理异常),则该异常将在 Lazy<T>.Value 属性的后续调用上再次缓存和引发该异常。如果您使用不指定初始化方法的 Lazy<T> 构造函数,则不会缓存 T 默认构造函数引发的异常。在这种情况下,随后调用 Lazy<T>.Value 属性可能会成功地初始化 Lazy<T> 实例。如果初始化方法递归访问 Lazy<T> 实例的 Value 属性,则引发 InvalidOperationException
PublicationOnly当多个线程尝试同时初始化一个 Lazy<T> 实例时,允许所有线程都运行初始化方法(如果没有初始化方法,则为默认构造函数)。完成初始化的第一个线程设置 Lazy<T> 实例的值。该值将返回给同时运行初始化方法的所有其他线程,除非该初始化方法对这些线程引发异常。争用线程创建的任何 T 实例都将被丢弃。如果初始化方法对任何线程引发异常,则该异常会从在该线程上的Lazy<T>.Value 属性传播出去。不缓存该异常。IsValueCreated 属性的值仍然为 false,并且随后通过其中引发异常的线程或通过其他线程对 Value 属性的调用会导致初始化方法再次运行。如果初始化方法递归访问 Lazy<T> 实例的 Value 属性,则不会引发异常。

使用此枚举指定 Lazy<T> 构造函数的 mode 参数。所有构造函数对线程同步的影响可以根据此枚举来描述,不管它们有没有 mode 参数。

Lazy<T> 实例由用户指定初始化方法或 T 的默认构造函数初始化。初始化方法通过 Lazy<T> 构造函数的 valueFactory 参数指定。该方法返回 T 的实例,即通过 Lazy<T> 的实例延迟实例化的类型。如果构造函数没有 valueFactory 参数,T 的默认构造函数用于初始化 Lazy<T>实例。在这两种情况下,初始化发生在第一次调用 Lazy<T>.Value 属性的时候。

除了指定 Lazy<T> 实例的线程安全之外,此枚举还影响异常缓存。当从 Lazy<T> 实例缓存异常时,只有一次机会来初始化实例。如果首次调用 Lazy<T>.Value属性时引发异常,则会缓存该异常并在随后调用 Lazy<T>.Value 属性时再次引发该异常。缓存异常的优势在于任意两个线程总会得到相同的结果,甚至是在发生错误的时候。

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

模式

使用初始化方法

将默认构造函数用于 T

None

Cached(缓存的请求)

不缓存

PublicationOnly

不缓存

不缓存

ExecutionAndPublication

Cached(缓存的请求)

不缓存

Windows Phone OS

受以下版本支持: 8.0

Microsoft 正在进行一项网上调查,以了解您对 MSDN 网站的意见。 如果您选择参加,我们将会在您离开 MSDN 网站时向您显示该网上调查。

是否要参加?
显示:
© 2015 Microsoft