LazyThreadSafetyMode 枚举

定义

指定 Lazy<T> 实例如何同步多个线程间的访问。Specifies how a Lazy<T> instance synchronizes access among multiple threads.

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

字段

ExecutionAndPublication 2

使用锁来确保只有一个线程可以在线程安全的方式下初始化 Lazy<T> 实例。Locks are used to ensure that only a single thread can initialize a Lazy<T> instance in a thread-safe manner. 如果初始化方法(如果没有初始化方法,则为无参数构造函数)在内部使用锁,则可能会发生死锁。If the initialization method (or the parameterless constructor, if there is no initialization method) uses locks internally, deadlocks can occur. 如果使用指定初始化方法(valueFactory 参数)的 Lazy<T> 构造函数,并且如果此初始化方法在你首次调用 Value 属性时引发异常(或无法处理异常),则会缓存该异常并在随后调用 Value 属性时再次引发该异常。If you use a Lazy<T> constructor that specifies an initialization method (valueFactory parameter), and if that initialization method throws an exception (or fails to handle an exception) the first time you call the Value property, then the exception is cached and thrown again on subsequent calls to the Value property. 如果使用不指定初始化方法的 Lazy<T> 构造函数,则不会缓存 T 无参数构造函数引发的异常。If you use a Lazy<T> constructor that does not specify an initialization method, exceptions that are thrown by the parameterless constructor for T are not cached. 在此情况下,对 Value 属性进行后续调用可成功初始化 Lazy<T> 实例。In that case, a subsequent call to the Value property might successfully initialize the Lazy<T> instance. 如果初始化方法递归访问 Lazy<T> 实例的 Value 属性,则引发 InvalidOperationExceptionIf the initialization method recursively accesses the Value property of the Lazy<T> instance, an InvalidOperationException is thrown.

None 0

Lazy<T> 实例不是线程安全的;如果从多个线程访问该实例,则其行为不确定。The Lazy<T> instance is not thread safe; if the instance is accessed from multiple threads, its behavior is undefined. 仅应在高性能至关重要并且保证决不会从多个线程初始化 Lazy<T> 实例时才使用该模式。Use this mode only when high performance is crucial and the Lazy<T> instance is guaranteed never to be initialized from more than one thread. 如果使用指定初始化方法(valueFactory 参数)的 Lazy<T> 构造函数,并且如果此初始化方法在你首次调用 Value 属性时引发异常(或无法处理异常),则会缓存该异常并在随后调用 Value 属性时再次引发该异常。If you use a Lazy<T> constructor that specifies an initialization method (valueFactory parameter), and if that initialization method throws an exception (or fails to handle an exception) the first time you call the Value property, then the exception is cached and thrown again on subsequent calls to the Value property. 如果使用不指定初始化方法的 Lazy<T> 构造函数,则不会缓存 T 无参数构造函数引发的异常。If you use a Lazy<T> constructor that does not specify an initialization method, exceptions that are thrown by the parameterless constructor for T are not cached. 在此情况下,对 Value 属性进行后续调用可成功初始化 Lazy<T> 实例。In that case, a subsequent call to the Value property might successfully initialize the Lazy<T> instance. 如果初始化方法递归访问 Lazy<T> 实例的 Value 属性,则引发 InvalidOperationExceptionIf the initialization method recursively accesses the Value property of the Lazy<T> instance, an InvalidOperationException is thrown.

PublicationOnly 1

当多个线程尝试同时初始化一个 Lazy<T> 实例时,允许所有线程都运行初始化方法(如果没有初始化方法,则运行无参数构造函数)。When multiple threads try to initialize a Lazy<T> instance simultaneously, all threads are allowed to run the initialization method (or the parameterless constructor, if there is no initialization method). 完成初始化的第一个线程设置 Lazy<T> 实例的值。The first thread to complete initialization sets the value of the Lazy<T> instance. 该值将返回给同时运行初始化方法的其他所有线程,除非初始化方法对这些线程引发异常。That value is returned to any other threads that were simultaneously running the initialization method, unless the initialization method throws exceptions on those threads. 争用线程创建的任何 T 实例都将被放弃。Any instances of T that were created by the competing threads are discarded. 如果初始化方法对任何线程引发异常,则该异常会从该线程上的 Value 属性传播出去。If the initialization method throws an exception on any thread, the exception is propagated out of the Value property on that thread. 不缓存该异常。The exception is not cached. IsValueCreated 属性的值仍然为 false,并且随后通过其中引发异常的线程或通过其他线程对 Value 属性的调用会导致初始化方法再次运行。The value of the IsValueCreated property remains false, and subsequent calls to the Value property, either by the thread where the exception was thrown or by other threads, cause the initialization method to run again. 如果初始化方法递归访问 Value 实例的 Lazy<T> 属性,则不会引发异常。If the initialization method recursively accesses the Value property of the Lazy<T> instance, no exception is thrown.

注解

使用此枚举指定mode Lazy<T>构造函数的参数。Use this enumeration to specify the mode parameter of Lazy<T> constructors. 所有构造函数对线程同步的影响都可以根据此枚举进行描述, 无论它们是否具有mode参数。The effects of all constructors on thread synchronization can be described in terms of this enumeration, whether or not they have mode parameters.

实例通过用户指定的初始化方法或的无参数构造函数进行T初始化。 Lazy<T>A Lazy<T> instance is initialized either by a user-specified initialization method or by the parameterless constructor for T. 初始化方法由valueFactory Lazy<T>构造函数的参数指定。The initialization method is specified by the valueFactory parameter of a Lazy<T> constructor. 方法返回的T实例, 它是Lazy<T>实例延迟实例化的类型。The method returns an instance of T, which is the type that is lazily instantiated by the instance of Lazy<T>. 如果构造函数valueFactory没有参数, T则使用的无参数构造函数来初始化该Lazy<T>实例。If a constructor does not have a valueFactory parameter, the parameterless constructor for T is used to initialize the Lazy<T> instance. 在任一情况下, 第一次调用Lazy<T>.Value属性时都会发生初始化。In either case, initialization occurs the first time you call the Lazy<T>.Value property.

除了指定Lazy<T>实例的线程安全外, 此枚举还会影响异常缓存。In addition to specifying the thread safety of a Lazy<T> instance, this enumeration affects exception caching. Lazy<T>实例缓存异常时, 只会有一个机会初始化实例。When exceptions are cached for a Lazy<T> instance, you get only one chance to initialize the instance. 如果在首次调用Lazy<T>.Value属性时引发了异常, 则会缓存该异常并在对属性的Lazy<T>.Value所有后续调用中再次引发该异常。If an exception is thrown the first time you call the Lazy<T>.Value property, that exception is cached and rethrown on all subsequent calls to the Lazy<T>.Value property. 缓存异常的优点是, 即使发生错误, 任何两个线程总是获得相同的结果。The advantage of caching exceptions is that any two threads always get the same result, even when errors occur.

指定 PublicationOnly 模式时, 永远不会缓存异常。When you specify the PublicationOnly mode, exceptions are never cached. 如果指定 "无" 或 "ExecutionAndPublication", 则缓存将取决于您指定的是初始化方法还是T允许使用无参数的构造函数。When you specify None or ExecutionAndPublication, caching depends on whether you specify an initialization method or allow the parameterless constructor for T to be used. 指定初始化方法可启用这两种模式的异常缓存。Specifying an initialization method enables exception caching for these two modes. 初始化方法非常简单。The initialization method can be very simple. 例如, 它可能会调用中的参数构造T函数new Lazy<Contents>(() => new Contents(), mode) : C#在中New Lazy(Of Contents)(Function() New Contents()) , 或在 Visual Basic 中。For example, it might call the parameterless constructor for T: new Lazy<Contents>(() => new Contents(), mode) in C#, or New Lazy(Of Contents)(Function() New Contents()) in Visual Basic. 如果你使用不指定初始化方法的构造函数, 则不T会缓存的无参数构造函数引发的异常。If you use a constructor that does not specify an initialization method, exceptions that are thrown by the parameterless constructor for T are not cached. 下表汇总了异常的缓存行为。The following table summarizes exception caching behavior.

模式Mode 使用初始化方法Using initialization method 使用无参数构造函数TUsing parameterless constructor for T
NoneNone 已缓存Cached 未缓存Not cached
PublicationOnlyPublicationOnly 未缓存Not cached 未缓存Not cached
ExecutionAndPublicationExecutionAndPublication 已缓存Cached 未缓存Not cached

适用于

另请参阅