System.Lazy<T> Class

Provides support for lazy initialization.

See Also: Lazy<T> Members

Syntax

[System.Diagnostics.DebuggerDisplay("ThreadSafetyMode={Mode}, IsValueCreated={IsValueCreated}, IsValueFaulted={IsValueFaulted}, Value={ValueForDebugDisplay}")]
[System.Runtime.InteropServices.ComVisible(false)]
public class Lazy<T>

Type Parameters

T
Documentation for this section has not yet been entered.

Remarks

Use lazy initialization to defer the creation of a large or resource-intensive object, or the execution of a resource-intensive task, particularly when such creation or execution might not occur during the lifetime of the program.

To prepare for lazy initialization, you create an instance of Lazy`1. The type argument of the Lazy`1 object that you create specifies the type of the object that you want to initialize lazily. The constructor that you use to create the Lazy`1 object determines the characteristics of the initialization. Lazy initialization occurs the first time the Lazy`1.Value property is accessed.

In most cases, choosing a constructor depends on your answers to two questions:

The following table shows which constructor to choose, based on these two factors:

Multiple threads

Lazy`1.#ctor

Lazy`1.#ctor(Func<`0>)

One thread

Lazy`1.#ctor(bool) with isThreadSafe set to false.

Lazy`1.#ctor(Func<`0>,System.Boolean) with isThreadSafe set to false.

You can use a lambda expression to specify the factory method. This keeps all the initialization code in one place. The lambda expression captures the context, including any arguments you pass to the lazily initialized object's constructor.

Exception caching  When you use factory methods, exceptions are cached. That is, if the factory method throws an exception the first time a thread tries to access the Lazy`1.Value property of the Lazy`1 object, the same exception is thrown on every subsequent attempt. This ensures that every call to the Lazy`1.Value property produces the same result and avoids subtle errors that might arise if different threads get different results. The Lazy`1 stands in for an actual T that otherwise would have been initialized at some earlier point, usually during startup. A failure at that earlier point is usually fatal. If there is a potential for a recoverable failure, we recommend that you build the retry logic into the initialization routine (in this case, the factory method), just as you would if you weren’t using lazy initialization.

Alternative to locking  In certain situations, you might want to avoid the overhead of the Lazy`1 object's default locking behavior. In rare situations, there might be a potential for deadlocks. In such cases, you can use the Lazy`1.#ctor(System.Threading.LazyThreadSafetyMode) or Lazy`1.#ctor(Func<`0>,System.Threading.LazyThreadSafetyMode) constructor, and specify System.Threading.LazyThreadSafetyMode.PublicationOnly. This enables the Lazy`1 object to create a copy of the lazily initialized object on each of several threads if the threads call the Lazy`1.Value property simultaneously. The Lazy`1 object ensures that all threads use the same instance of the lazily initialized object and discards the instances that are not used. Thus, the cost of reducing the locking overhead is that your program might sometimes create and discard extra copies of an expensive object. In most cases, this is unlikely. The examples for the Lazy`1.#ctor(System.Threading.LazyThreadSafetyMode) and Lazy`1.#ctor(Func<`0>,System.Threading.LazyThreadSafetyMode) constructors demonstrate this behavior.

Note:

When you specify System.Threading.LazyThreadSafetyMode.PublicationOnly, exceptions are never cached, even if you specify a factory method.

Equivalent constructors  In addition to enabling the use of System.Threading.LazyThreadSafetyMode.PublicationOnly, the Lazy`1.#ctor(System.Threading.LazyThreadSafetyMode) and Lazy`1.#ctor(Func<`0>,System.Threading.LazyThreadSafetyMode) constructors can duplicate the functionality of the other constructors. The following table shows the parameter values that produce equivalent behavior.

Fully thread safe; uses locking to ensure that only one thread initializes the value.

System.Threading.LazyThreadSafetyMode.ExecutionAndPublication

true

All such constructors are fully thread safe.

Not thread safe.

System.Threading.LazyThreadSafetyMode.None

false

Not applicable.

Fully thread safe; threads race to initialize the value.

System.Threading.LazyThreadSafetyMode.PublicationOnly

Not applicable.

Not applicable.

Other capabilities  For information about the use of Lazy`1 with thread-static fields, or as the backing store for properties, see Lazy Initialization.

Requirements

Namespace: System
Assembly: mscorlib (in mscorlib.dll)
Assembly Versions: 4.0.0.0