Lazy<T> Lazy<T> Lazy<T> Lazy<T> Constructors

定義

オーバーロード

Lazy<T>() Lazy<T>() Lazy<T>()

Lazy<T> クラスの新しいインスタンスを初期化します。Initializes a new instance of the Lazy<T> class. 遅延初期化が発生した場合、対象の型の既定のコンストラクターが使用されます。When lazy initialization occurs, the default constructor of the target type is used.

Lazy<T>(Boolean) Lazy<T>(Boolean) Lazy<T>(Boolean) Lazy<T>(Boolean)

Lazy<T> クラスの新しいインスタンスを初期化します。Initializes a new instance of the Lazy<T> class. 遅延初期化が発生した場合、対象の型の既定のコンストラクターと指定された初期化モードが使用されます。When lazy initialization occurs, the default constructor of the target type and the specified initialization mode are used.

Lazy<T>(Func<T>) Lazy<T>(Func<T>) Lazy<T>(Func<T>) Lazy<T>(Func<T>)

Lazy<T> クラスの新しいインスタンスを初期化します。Initializes a new instance of the Lazy<T> class. 遅延初期化が発生した場合、指定された初期化関数が使用されます。When lazy initialization occurs, the specified initialization function is used.

Lazy<T>(LazyThreadSafetyMode) Lazy<T>(LazyThreadSafetyMode) Lazy<T>(LazyThreadSafetyMode) Lazy<T>(LazyThreadSafetyMode)

T の既定のコンストラクターと指定されたスレッド セーフ モードを使用する Lazy<T> クラスの新しいインスタンスを初期化します。Initializes a new instance of the Lazy<T> class that uses the default constructor of T and the specified thread-safety mode.

Lazy<T>(T) Lazy<T>(T) Lazy<T>(T) Lazy<T>(T)

事前に初期化され、指定された値を使用する Lazy<T> クラスの新しいインスタンスを初期化します。Initializes a new instance of the Lazy<T> class that uses a preinitialized specified value.

Lazy<T>(Func<T>, Boolean) Lazy<T>(Func<T>, Boolean) Lazy<T>(Func<T>, Boolean) Lazy<T>(Func<T>, Boolean)

Lazy<T> クラスの新しいインスタンスを初期化します。Initializes a new instance of the Lazy<T> class. 遅延初期化が発生した場合、指定された初期化関数および初期化モードが使用されます。When lazy initialization occurs, the specified initialization function and initialization mode are used.

Lazy<T>(Func<T>, LazyThreadSafetyMode) Lazy<T>(Func<T>, LazyThreadSafetyMode) Lazy<T>(Func<T>, LazyThreadSafetyMode) Lazy<T>(Func<T>, LazyThreadSafetyMode)

指定された初期化関数とスレッド セーフ モードを使用する Lazy<T> クラスの新しいインスタンスを初期化します。Initializes a new instance of the Lazy<T> class that uses the specified initialization function and thread-safety mode.

Lazy<T>() Lazy<T>() Lazy<T>()

Lazy<T> クラスの新しいインスタンスを初期化します。Initializes a new instance of the Lazy<T> class. 遅延初期化が発生した場合、対象の型の既定のコンストラクターが使用されます。When lazy initialization occurs, the default constructor of the target type is used.

public:
 Lazy();
public Lazy ();
Public Sub New ()

次の例では、このコンス トラクターの使用を示します。The following example demonstrates the use of this constructor. 使用も示しています、Lazy<T>(Boolean)コンス トラクター (を指定するtrueisThreadSafe) およびLazy<T>(LazyThreadSafetyMode)コンス トラクター (を指定するLazyThreadSafetyMode.ExecutionAndPublicationmode)。It also illustrates the use of the Lazy<T>(Boolean) constructor (specifying true for isThreadSafe) and the Lazy<T>(LazyThreadSafetyMode) constructor (specifying LazyThreadSafetyMode.ExecutionAndPublication for mode). 別のコンス トラクターを切り替えるだけどのコンス トラクターをコメント アウトを変更します。To switch to a different constructor, just change which constructors are commented out.

この例では、複数あるスレッドのうちの 1 つによって遅れて初期化される LargeObject クラスを定義します。The example defines a LargeObject class that will be initialized lazily by one of several threads. このコード例での 2 つの主要な行は、初期化子と実際の初期化を作成します。The two key lines of code in this example are the creation of the initializer and the actual initialization. Main メソッドの開始時に、この例では LargeObject のスレッドセーフな遅延初期化子が作成されます。At the beginning of the Main method, the example creates the thread-safe lazy initializer for LargeObject:

lazyLargeObject = new Lazy<LargeObject>();

// The following lines show how to use other constructors to achieve exactly the
// same result as the previous line: 
//lazyLargeObject = new Lazy<LargeObject>(true);
//lazyLargeObject = new Lazy<LargeObject>(LazyThreadSafetyMode.ExecutionAndPublication);
lazyLargeObject = New Lazy(Of LargeObject)()

' The following lines show how to use other constructors to achieve exactly the
' same result as the previous line: 
'lazyLargeObject = New Lazy(Of LargeObject)(True)
'lazyLargeObject = New Lazy(Of LargeObject)(LazyThreadSafetyMode.ExecutionAndPublication)

例を作成し、ブロックの 3 つのスレッドを開始、ManualResetEventオブジェクトの例が、スレッドをすべて同時に解放できるようにします。The example creates and starts three threads that block on a ManualResetEvent object, so that the example can release the threads all at once. ThreadProc 3 つのスレッドのすべての呼び出しで使用されるメソッド、Valueを取得するプロパティ、LargeObjectインスタンス。The ThreadProc method that's used by all three threads calls the Value property to get the LargeObject instance:

LargeObject large = lazyLargeObject.Value;
Dim large As LargeObject = lazyLargeObject.Value

Lazy<T>クラスは 1 つのスレッドが作成できるように、ロックを提供、LargeObjectインスタンス。The Lazy<T> class provides locking, so that only one thread is allowed to create the LargeObject instance. この例では、すべて、他のスレッドが同じインスタンスを取得することを示します。The example demonstrates that the other threads all get the same instance.

注意

簡略化のために、この例では Lazy<T> のグローバル インスタンスを使用して、すべてのメソッドは static (Visual Basic の Shared) です。For simplicity, this example uses a global instance of Lazy<T>, and all the methods are static (Shared in Visual Basic). これらは、遅延初期化を使用するための要件ではありません。These are not requirements for the use of lazy initialization.

using System;
using System.Threading;

class Program
{
    static Lazy<LargeObject> lazyLargeObject = null;

    static void Main()
    {
        // The lazy initializer is created here. LargeObject is not created until the 
        // ThreadProc method executes.
        lazyLargeObject = new Lazy<LargeObject>();

        // The following lines show how to use other constructors to achieve exactly the
        // same result as the previous line: 
        //lazyLargeObject = new Lazy<LargeObject>(true);
        //lazyLargeObject = new Lazy<LargeObject>(LazyThreadSafetyMode.ExecutionAndPublication);


        Console.WriteLine(
            "\r\nLargeObject is not created until you access the Value property of the lazy" +
            "\r\ninitializer. Press Enter to create LargeObject.");
        Console.ReadLine();

        // Create and start 3 threads, passing the same blocking event to all of them.
        ManualResetEvent startingGate = new ManualResetEvent(false);
        Thread[] threads = { new Thread(ThreadProc), new Thread(ThreadProc), new Thread(ThreadProc) };
        foreach (Thread t in threads)
        {
            t.Start(startingGate);
        }

        // Give all 3 threads time to start and wait, then release them all at once.
        Thread.Sleep(100);
        startingGate.Set();

        // Wait for all 3 threads to finish. (The order doesn't matter.)
        foreach (Thread t in threads)
        {
            t.Join();
        }

        Console.WriteLine("\r\nPress Enter to end the program");
        Console.ReadLine();
    }


    static void ThreadProc(object state)
    {
        // Wait for the signal.
        ManualResetEvent waitForStart = (ManualResetEvent) state;
        waitForStart.WaitOne();

        LargeObject large = lazyLargeObject.Value;

        // The following line introduces an artificial delay, to exaggerate the race 
        // condition.
        Thread.Sleep(5); 

        // IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the  
        //            object after creation. You must lock the object before accessing it,
        //            unless the type is thread safe. (LargeObject is not thread safe.)
        lock(large)
        {
            large.Data[0] = Thread.CurrentThread.ManagedThreadId;
            Console.WriteLine("Initialized by thread {0}; last used by thread {1}.", 
                large.InitializedBy, large.Data[0]);
        }
    }
}

class LargeObject
{
    int initBy = 0;
    public int InitializedBy { get { return initBy; } }

    public LargeObject()
    {
        initBy = Thread.CurrentThread.ManagedThreadId;
        Console.WriteLine("LargeObject was created on thread id {0}.", initBy);
    }
    public long[] Data = new long[100000000];
}

/* This example produces output similar to the following:

LargeObject is not created until you access the Value property of the lazy
initializer. Press Enter to create LargeObject.

LargeObject was created on thread id 4.
Initialized by thread 4; last used by thread 3.
Initialized by thread 4; last used by thread 4.
Initialized by thread 4; last used by thread 5.

Press Enter to end the program
 */
Imports System
Imports System.Threading

Class Program
    Private Shared lazyLargeObject As Lazy(Of LargeObject) = Nothing

    Shared Sub Main()
        ' The lazy initializer is created here. LargeObject is not created until the 
        ' ThreadProc method executes.
        lazyLargeObject = New Lazy(Of LargeObject)()

        ' The following lines show how to use other constructors to achieve exactly the
        ' same result as the previous line: 
        'lazyLargeObject = New Lazy(Of LargeObject)(True)
        'lazyLargeObject = New Lazy(Of LargeObject)(LazyThreadSafetyMode.ExecutionAndPublication)


        Console.WriteLine( _
            vbCrLf & "LargeObject is not created until you access the Value property of the lazy" _
            & vbCrLf & "initializer. Press Enter to create LargeObject.")
        Console.ReadLine()

        ' Create and start 3 threads, passing the same blocking event to all of them.
        Dim startingGate As New ManualResetEvent(False)
        Dim threads() As Thread = { New Thread(AddressOf ThreadProc), 
            New Thread(AddressOf ThreadProc), New Thread(AddressOf ThreadProc) }
        For Each t As Thread In threads
            t.Start(startingGate)
        Next t

        ' Give all 3 threads time to start and wait, then release them all at once.
        Thread.Sleep(100)
        startingGate.Set()

        ' Wait for all 3 threads to finish. (The order doesn't matter.)
        For Each t As Thread In threads
            t.Join()
        Next t

        Console.WriteLine(vbCrLf & "Press Enter to end the program")
        Console.ReadLine()
    End Sub


    Private Shared Sub ThreadProc(ByVal state As Object)
        ' Wait for the signal.
        Dim waitForStart As ManualResetEvent = CType(state, ManualResetEvent)
        waitForStart.WaitOne()

        Dim large As LargeObject = lazyLargeObject.Value

        ' The following line introduces an artificial delay, to exaggerate the race 
        ' condition.
        Thread.Sleep(5)

        ' IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the  
        '            object after creation. You must lock the object before accessing it,
        '            unless the type is thread safe. (LargeObject is not thread safe.)
        SyncLock large
            large.Data(0) = Thread.CurrentThread.ManagedThreadId
            Console.WriteLine("Initialized by thread {0}; last used by thread {1}.", _
                large.InitializedBy, large.Data(0))
        End SyncLock
    End Sub
End Class

Class LargeObject
    Private initBy As Integer = 0
    Public ReadOnly Property InitializedBy() As Integer
        Get
            Return initBy
        End Get
    End Property

    Public Sub New()
        initBy = Thread.CurrentThread.ManagedThreadId
        Console.WriteLine("LargeObject was created on thread id {0}.", initBy)
    End Sub
    Public Data(100000000) As Long
End Class

' This example produces output similar to the following:
'
'LargeObject is not created until you access the Value property of the lazy
'initializer. Press Enter to create LargeObject.
'
'LargeObject was created on thread id 3.
'Initialized by thread 3; last used by thread 5.
'Initialized by thread 3; last used by thread 4.
'Initialized by thread 3; last used by thread 3.
'
'Press Enter to end the program

注釈

このコンス トラクターで作成されるインスタンスは、複数のスレッドから同時に使用される可能性があります。An instance that is created with this constructor may be used concurrently from multiple threads.

スレッドの安全性モード、Lazy<T>このコンス トラクターで初期化されたインスタンスがLazyThreadSafetyMode.ExecutionAndPublicationします。The thread safety mode of a Lazy<T> instance that is initialized with this constructor is LazyThreadSafetyMode.ExecutionAndPublication. 初期化しようとしている複数のスレッドとスレッドの安全性モードは、動作について説明します、Lazy<T>インスタンス。The thread safety mode describes the behavior when multiple threads try to initialize the Lazy<T> instance.

ALazy<T>このコンス トラクターで作成されたインスタンスには、例外をキャッシュしません。A Lazy<T> instance that is created with this constructor does not cache exceptions. 詳細については、Lazy<T> クラスまたは System.Threading.LazyThreadSafetyMode 列挙体の解説を参照してください。For more information, see the Lazy<T> class or the System.Threading.LazyThreadSafetyMode enumeration.

こちらもご覧ください

Lazy<T>(Boolean) Lazy<T>(Boolean) Lazy<T>(Boolean) Lazy<T>(Boolean)

Lazy<T> クラスの新しいインスタンスを初期化します。Initializes a new instance of the Lazy<T> class. 遅延初期化が発生した場合、対象の型の既定のコンストラクターと指定された初期化モードが使用されます。When lazy initialization occurs, the default constructor of the target type and the specified initialization mode are used.

public:
 Lazy(bool isThreadSafe);
public Lazy (bool isThreadSafe);
new Lazy<'T> : bool -> Lazy<'T>
Public Sub New (isThreadSafe As Boolean)

パラメーター

isThreadSafe
Boolean Boolean Boolean Boolean

このインスタンスを複数のスレッドで同時に使用できるようにする場合は true。インスタンスを一度に 1 つのスレッドでしか使用できないようにする場合は falsetrue to make this instance usable concurrently by multiple threads; false to make the instance usable by only one thread at a time.

次の例では、スレッド セーフである、遅れて初期化されるオブジェクトに対するすべてのアクセスが同じスレッドで発生するシナリオではない遅延初期化子を作成するこのコンス トラクターの使用を示します。The following example demonstrates the use of this constructor to create a lazy initializer that is not thread safe, for scenarios where all access to the lazily initialized object occurs on the same thread. 使用にも示しますが、Lazy<T>(LazyThreadSafetyMode)コンス トラクター (を指定するLazyThreadSafetyMode.Nonemodeします。It also demonstrates the use of the Lazy<T>(LazyThreadSafetyMode) constructor (specifying LazyThreadSafetyMode.None for mode. 別のコンス トラクターに切り替えると、同じコンス トラクターをコメント アウトを変更します。To switch to a different constructor, just change which constructor is commented out.

注意

マルチ スレッド シナリオでこのコンス トラクターを使用する方法を示すコードについて (を指定するtrueisThreadSafe)、例をご覧ください、Lazy<T>()コンス トラクター。For code that demonstrates how to use this constructor in multithreaded scenarios (specifying true for isThreadSafe), see the example for the Lazy<T>() constructor.

例では、定義、LargeObject遅れて初期化されるクラス。The example defines a LargeObject class that will be initialized lazily. Mainメソッドの例は、作成、Lazy<T>インスタンスと、一時停止します。In the Main method, the example creates a Lazy<T> instance and then pauses. 押したときに、 」と入力キー、例では、アクセス、Valueのプロパティ、Lazy<T>初期化が発生すると、インスタンス。When you press the Enter key, the example accesses the Value property of the Lazy<T> instance, which causes initialization to occur. コンス トラクター、LargeObjectクラスには、コンソール メッセージが表示されます。The constructor of the LargeObject class displays a console message.

注意

簡略化のために、この例では Lazy<T> のグローバル インスタンスを使用して、すべてのメソッドは static (Visual Basic の Shared) です。For simplicity, this example uses a global instance of Lazy<T>, and all the methods are static (Shared in Visual Basic). これらは、遅延初期化を使用するための要件ではありません。These are not requirements for the use of lazy initialization.

using System;
using System.Threading;

class Program
{
    static Lazy<LargeObject> lazyLargeObject = null;

    static void Main()
    {
        // The lazy initializer is created here. LargeObject is not created until the 
        // ThreadProc method executes.
        lazyLargeObject = new Lazy<LargeObject>(false);

        // The following lines show how to use other constructors to achieve exactly the
        // same result as the previous line: 
        //lazyLargeObject = new Lazy<LargeObject>(LazyThreadSafetyMode.None);


        Console.WriteLine(
            "\r\nLargeObject is not created until you access the Value property of the lazy" +
            "\r\ninitializer. Press Enter to create LargeObject.");
        Console.ReadLine();

        LargeObject large = lazyLargeObject.Value;

        large.Data[11] = 89;

        Console.WriteLine("\r\nPress Enter to end the program");
        Console.ReadLine();
    }
}

class LargeObject
{
    public LargeObject()
    {
        Console.WriteLine("LargeObject was created on thread id {0}.", 
            Thread.CurrentThread.ManagedThreadId);
    }
    public long[] Data = new long[100000000];
}

/* This example produces output similar to the following:

LargeObject is not created until you access the Value property of the lazy
initializer. Press Enter to create LargeObject.

LargeObject was created on thread id 1.

Press Enter to end the program
 */
Imports System
Imports System.Threading

Friend Class Program
    Private Shared lazyLargeObject As Lazy(Of LargeObject) = Nothing

    Shared Sub Main()
        ' The lazy initializer is created here. LargeObject is not created until the 
        ' ThreadProc method executes.
        lazyLargeObject = New Lazy(Of LargeObject)(False)

        ' The following lines show how to use other constructors to achieve exactly the
        ' same result as the previous line: 
        'lazyLargeObject = new Lazy<LargeObject>(LazyThreadSafetyMode.None);


        Console.WriteLine( _
            vbCrLf & "LargeObject is not created until you access the Value property of the lazy" _
            & vbCrLf & "initializer. Press Enter to create LargeObject.")
        Console.ReadLine()

        Dim large As LargeObject = lazyLargeObject.Value

        large.Data(11) = 89

        Console.WriteLine(vbCrLf & "Press Enter to end the program")
        Console.ReadLine()
    End Sub
End Class

Friend Class LargeObject
    Public Sub New()
        Console.WriteLine("LargeObject was created on thread id {0}.", _
            Thread.CurrentThread.ManagedThreadId)
    End Sub
    Public Data(100000000) As Long
End Class

' This example produces output similar to the following:
'
'LargeObject is not created until you access the Value property of the lazy
'initializer. Press Enter to create LargeObject.
'
'LargeObject was created on thread id 1.
'
'Press Enter to end the program

注釈

スレッドの安全性モード、Lazy<T>このコンス トラクターで初期化されたインスタンスがLazyThreadSafetyMode.ExecutionAndPublication場合isThreadSafetrue、それ以外のモードはLazyThreadSafetyMode.Noneします。The thread safety mode of a Lazy<T> instance that is initialized with this constructor is LazyThreadSafetyMode.ExecutionAndPublication if isThreadSafe is true; otherwise, the mode is LazyThreadSafetyMode.None. 初期化しようとしている複数のスレッドとスレッドの安全性モードは、動作について説明します、Lazy<T>インスタンス。The thread safety mode describes the behavior when multiple threads try to initialize the Lazy<T> instance. 指定する、LazyThreadSafetyMode.PublicationOnlyモードを使用して、Lazy<T>(Func<T>, LazyThreadSafetyMode)またはLazy<T>(LazyThreadSafetyMode)コンス トラクター。To specify the LazyThreadSafetyMode.PublicationOnly mode, use the Lazy<T>(Func<T>, LazyThreadSafetyMode) or Lazy<T>(LazyThreadSafetyMode) constructor.

ALazy<T>このコンス トラクターで作成されたインスタンスには、例外をキャッシュしません。A Lazy<T> instance that is created with this constructor does not cache exceptions. 詳細については、Lazy<T> クラスまたは System.Threading.LazyThreadSafetyMode 列挙体の解説を参照してください。For more information, see the Lazy<T> class or the System.Threading.LazyThreadSafetyMode enumeration.

こちらもご覧ください

Lazy<T>(Func<T>) Lazy<T>(Func<T>) Lazy<T>(Func<T>) Lazy<T>(Func<T>)

Lazy<T> クラスの新しいインスタンスを初期化します。Initializes a new instance of the Lazy<T> class. 遅延初期化が発生した場合、指定された初期化関数が使用されます。When lazy initialization occurs, the specified initialization function is used.

public:
 Lazy(Func<T> ^ valueFactory);
public Lazy (Func<T> valueFactory);
new Lazy<'T> : Func<'T> -> Lazy<'T>
Public Sub New (valueFactory As Func(Of T))

パラメーター

valueFactory
Func<T>

必要時に遅延初期化される値を生成するために呼び出されるデリゲート。The delegate that is invoked to produce the lazily initialized value when it is needed.

例外

valueFactorynullです。valueFactory is null.

次の例では、遅延初期化で例外キャッシュを提供するこのコンス トラクターの使用を示します。The following example demonstrates the use of this constructor to provide lazy initialization with exception caching. 使用にも示しますが、Lazy<T>(Func<T>, Boolean)コンス トラクター (を指定するtrueisThreadSafe) とLazy<T>(Func<T>, LazyThreadSafetyMode)コンス トラクター (を指定するLazyThreadSafetyMode.ExecutionAndPublicationmode)。It also demonstrates the use of the Lazy<T>(Func<T>, Boolean) constructor (specifying true for isThreadSafe) and the Lazy<T>(Func<T>, LazyThreadSafetyMode) constructor (specifying LazyThreadSafetyMode.ExecutionAndPublication for mode). 別のコンス トラクターを切り替えるだけどのコンス トラクターをコメント アウトを変更します。To switch to a different constructor, just change which constructors are commented out.

この例では、複数あるスレッドのうちの 1 つによって遅れて初期化される LargeObject クラスを定義します。The example defines a LargeObject class that will be initialized lazily by one of several threads. コードの 3 つの主要セクションが、初期化子、実際の初期化のコンス トラクターの作成を示しています、LargeObjectクラスは、例外キャッシュを示します。The three key sections of code illustrate the creation of the initializer, the actual initialization, and the constructor of the LargeObject class, which demonstrates exception caching. Main メソッドの開始時に、この例では LargeObject のスレッドセーフな遅延初期化子が作成されます。At the beginning of the Main method, the example creates the thread-safe lazy initializer for LargeObject:

lazyLargeObject = new Lazy<LargeObject>(InitLargeObject);

// The following lines show how to use other constructors to achieve exactly the
// same result as the previous line: 
//lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, true);
//lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, LazyThreadSafetyMode.ExecutionAndPublication);
lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject)

' The following lines show how to use other constructors to achieve exactly the
' same result as the previous line: 
'lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, True)
'lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, LazyThreadSafetyMode.ExecutionAndPublication)

例では、作成し、次の 3 つのスレッドを開始します。The example creates and starts three threads. ThreadProc 3 つのスレッドのすべての呼び出しで使用されるメソッド、Valueを取得するプロパティ、LargeObjectインスタンス。The ThreadProc method that's used by all three threads calls the Value property to get the LargeObject instance:

try
{
    LargeObject large = lazyLargeObject.Value;

    // IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the  
    //            object after creation. You must lock the object before accessing it,
    //            unless the type is thread safe. (LargeObject is not thread safe.)
    lock(large)
    {
        large.Data[0] = Thread.CurrentThread.ManagedThreadId;
        Console.WriteLine("Initialized by thread {0}; last used by thread {1}.", 
            large.InitializedBy, large.Data[0]);
    }
}
catch (ApplicationException aex)
{
    Console.WriteLine("Exception: {0}", aex.Message);
}
Try
    Dim large As LargeObject = lazyLargeObject.Value

    ' IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the  
    '            object after creation. You must lock the object before accessing it,
    '            unless the type is thread safe. (LargeObject is not thread safe.)
    SyncLock large
        large.Data(0) = Thread.CurrentThread.ManagedThreadId
        Console.WriteLine("Initialized by thread {0}; last used by thread {1}.", _
            large.InitializedBy, large.Data(0))
    End SyncLock
Catch aex As ApplicationException
    Console.WriteLine("Exception: {0}", aex.Message)
End Try

コンス トラクター、LargeObjectクラス、コードの 3 番目のキー セクションが最初に例外をスロー、LargeObjectインスタンスが作成されますが、発生するインスタンスの作成は、その後。In the constructor of the LargeObject class, the third key section of code throws an exception the first time a LargeObject instance is created, but thereafter allows instance creation to occur:

static int instanceCount = 0;
public LargeObject()
{
    if (1 == Interlocked.Increment(ref instanceCount))
    {
        throw new ApplicationException("Throw only ONCE.");
    }

    initBy = Thread.CurrentThread.ManagedThreadId;
    Console.WriteLine("LargeObject was created on thread id {0}.", initBy);
}
Private Shared instanceCount As Integer = 0
Public Sub New()
    If 1 = Interlocked.Increment(instanceCount) Then
        Throw New ApplicationException("Throw only ONCE.")
    End If

    initBy = Thread.CurrentThread.ManagedThreadId
    Console.WriteLine("LargeObject was created on thread id {0}.", initBy)
End Sub

例では、実行時のインスタンスを作成しようとしています。 最初のスレッドLargeObject失敗し、例外がキャッチされます。When the example is run, the first thread that tries to create an instance of LargeObject fails, and the exception is caught. 次のスレッドは、インスタンスの作成で正常に思うかもしれませんが、Lazy<T>オブジェクトには、例外がキャッシュされています。You might expect that the next thread would successfully create an instance, but the Lazy<T> object has cached the exception. このため、次の 3 つのすべてのスレッドは、例外をスローします。Because of this, all three threads throw the exception.

注意

簡略化のために、この例では Lazy<T> のグローバル インスタンスを使用して、すべてのメソッドは static (Visual Basic の Shared) です。For simplicity, this example uses a global instance of Lazy<T>, and all the methods are static (Shared in Visual Basic). これらは、遅延初期化を使用するための要件ではありません。These are not requirements for the use of lazy initialization.

using System;
using System.Threading;

class Program
{
    static Lazy<LargeObject> lazyLargeObject = null;

    static LargeObject InitLargeObject()
    {
        return new LargeObject();
    }


    static void Main()
    {
        // The lazy initializer is created here. LargeObject is not created until the 
        // ThreadProc method executes.
        lazyLargeObject = new Lazy<LargeObject>(InitLargeObject);

        // The following lines show how to use other constructors to achieve exactly the
        // same result as the previous line: 
        //lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, true);
        //lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, LazyThreadSafetyMode.ExecutionAndPublication);


        Console.WriteLine(
            "\r\nLargeObject is not created until you access the Value property of the lazy" +
            "\r\ninitializer. Press Enter to create LargeObject.");
        Console.ReadLine();

        // Create and start 3 threads, each of which tries to use LargeObject.
        Thread[] threads = { new Thread(ThreadProc), new Thread(ThreadProc), new Thread(ThreadProc) };
        foreach (Thread t in threads)
        {
            t.Start();
        }

        // Wait for all 3 threads to finish. (The order doesn't matter.)
        foreach (Thread t in threads)
        {
            t.Join();
        }

        Console.WriteLine("\r\nPress Enter to end the program");
        Console.ReadLine();
    }


    static void ThreadProc(object state)
    {
        try
        {
            LargeObject large = lazyLargeObject.Value;

            // IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the  
            //            object after creation. You must lock the object before accessing it,
            //            unless the type is thread safe. (LargeObject is not thread safe.)
            lock(large)
            {
                large.Data[0] = Thread.CurrentThread.ManagedThreadId;
                Console.WriteLine("Initialized by thread {0}; last used by thread {1}.", 
                    large.InitializedBy, large.Data[0]);
            }
        }
        catch (ApplicationException aex)
        {
            Console.WriteLine("Exception: {0}", aex.Message);
        }
    }
}

class LargeObject
{
    int initBy = 0;
    public int InitializedBy { get { return initBy; } }

    static int instanceCount = 0;
    public LargeObject()
    {
        if (1 == Interlocked.Increment(ref instanceCount))
        {
            throw new ApplicationException("Throw only ONCE.");
        }

        initBy = Thread.CurrentThread.ManagedThreadId;
        Console.WriteLine("LargeObject was created on thread id {0}.", initBy);
    }
    public long[] Data = new long[100000000];
}

/* This example produces output similar to the following:

LargeObject is not created until you access the Value property of the lazy
initializer. Press Enter to create LargeObject.

Exception: Throw only ONCE.
Exception: Throw only ONCE.
Exception: Throw only ONCE.

Press Enter to end the program
 */
Imports System
Imports System.Threading

Friend Class Program
    Private Shared lazyLargeObject As Lazy(Of LargeObject) = Nothing

    Private Shared Function InitLargeObject() As LargeObject
        Return New LargeObject()
    End Function


    Shared Sub Main()
        ' The lazy initializer is created here. LargeObject is not created until the 
        ' ThreadProc method executes.
        lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject)

        ' The following lines show how to use other constructors to achieve exactly the
        ' same result as the previous line: 
        'lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, True)
        'lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, LazyThreadSafetyMode.ExecutionAndPublication)


        Console.WriteLine(vbCrLf _
            & "LargeObject is not created until you access the Value property of the lazy" _
            & vbCrLf & "initializer. Press Enter to create LargeObject.")
        Console.ReadLine()

        ' Create and start 3 threads, each of which tries to use LargeObject.
        Dim threads() As Thread = { New Thread(AddressOf ThreadProc), _
            New Thread(AddressOf ThreadProc), New Thread(AddressOf ThreadProc) }
        For Each t As Thread In threads
            t.Start()
        Next t

        ' Wait for all 3 threads to finish. (The order doesn't matter.)
        For Each t As Thread In threads
            t.Join()
        Next t

        Console.WriteLine(vbCrLf & "Press Enter to end the program")
        Console.ReadLine()
    End Sub


    Private Shared Sub ThreadProc(ByVal state As Object)
        Try
            Dim large As LargeObject = lazyLargeObject.Value

            ' IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the  
            '            object after creation. You must lock the object before accessing it,
            '            unless the type is thread safe. (LargeObject is not thread safe.)
            SyncLock large
                large.Data(0) = Thread.CurrentThread.ManagedThreadId
                Console.WriteLine("Initialized by thread {0}; last used by thread {1}.", _
                    large.InitializedBy, large.Data(0))
            End SyncLock
        Catch aex As ApplicationException
            Console.WriteLine("Exception: {0}", aex.Message)
        End Try
    End Sub
End Class

Friend Class LargeObject
    Private initBy As Integer = 0
    Public ReadOnly Property InitializedBy() As Integer
        Get
            Return initBy
        End Get
    End Property

    Private Shared instanceCount As Integer = 0
    Public Sub New()
        If 1 = Interlocked.Increment(instanceCount) Then
            Throw New ApplicationException("Throw only ONCE.")
        End If

        initBy = Thread.CurrentThread.ManagedThreadId
        Console.WriteLine("LargeObject was created on thread id {0}.", initBy)
    End Sub
    Public Data(99999999) As Long
End Class

' This example produces output similar to the following:
'
'LargeObject is not created until you access the Value property of the lazy
'initializer. Press Enter to create LargeObject.
'
'Exception: Throw only ONCE.
'Exception: Throw only ONCE.
'Exception: Throw only ONCE.
'
'Press Enter to end the program
' 

注釈

このコンス トラクターで作成されるインスタンスは、複数のスレッドから同時に使用される可能性があります。An instance that is created with this constructor may be used concurrently from multiple threads.

スレッドの安全性モード、Lazy<T>このコンス トラクターで初期化されたインスタンスがLazyThreadSafetyMode.ExecutionAndPublicationします。The thread safety mode of a Lazy<T> instance that is initialized with this constructor is LazyThreadSafetyMode.ExecutionAndPublication. 初期化しようとしている複数のスレッドとスレッドの安全性モードは、動作について説明します、Lazy<T>インスタンス。The thread safety mode describes the behavior when multiple threads try to initialize the Lazy<T> instance.

によってスローされる例外valueFactoryキャッシュされます。Exceptions that are thrown by valueFactory are cached. 詳細については、Lazy<T> クラスまたは System.Threading.LazyThreadSafetyMode 列挙体の解説を参照してください。For more information, see the Lazy<T> class or the System.Threading.LazyThreadSafetyMode enumeration.

こちらもご覧ください

Lazy<T>(LazyThreadSafetyMode) Lazy<T>(LazyThreadSafetyMode) Lazy<T>(LazyThreadSafetyMode) Lazy<T>(LazyThreadSafetyMode)

T の既定のコンストラクターと指定されたスレッド セーフ モードを使用する Lazy<T> クラスの新しいインスタンスを初期化します。Initializes a new instance of the Lazy<T> class that uses the default constructor of T and the specified thread-safety mode.

public:
 Lazy(System::Threading::LazyThreadSafetyMode mode);
public Lazy (System.Threading.LazyThreadSafetyMode mode);
new Lazy<'T> : System.Threading.LazyThreadSafetyMode -> Lazy<'T>
Public Sub New (mode As LazyThreadSafetyMode)

パラメーター

mode
LazyThreadSafetyMode LazyThreadSafetyMode LazyThreadSafetyMode LazyThreadSafetyMode

スレッド セーフ モードを指定する列挙値の 1 つ。One of the enumeration values that specifies the thread safety mode.

例外

mode に無効な値が含まれています。mode contains an invalid value.

次の例では、複数のスレッドが競合するオブジェクトの遅延作成を遅延初期化子を作成するこのコンス トラクターの使用を示します。The following example demonstrates the use of this constructor to create a lazy initializer that enables multiple threads to race to create an object lazily. 複数のスレッドが、インスタンスの作成に成功可能性がありますが、すべてのスレッドが最初に作成されたインスタンスを使用します。Multiple threads might succeed in creating instances, but all threads use the instance that was created first.

注意

シングル スレッド シナリオでこのコンス トラクターを使用する方法を示す例については (を指定するLazyThreadSafetyMode.Nonemode) を参照してください、Lazy<T>(Boolean)コンス トラクター。For an example that demonstrates how to use this constructor in single-threaded scenarios (specifying LazyThreadSafetyMode.None for mode), see the Lazy<T>(Boolean) constructor. このコンス トラクターを使用して、競合状態がマルチ スレッド シナリオではなく、ロックを提供する方法を示す例については (を指定するLazyThreadSafetyMode.ExecutionAndPublicationmode) を参照してください、Lazy<T>()コンス トラクター。For an example that demonstrates how to use this constructor to provide locking instead of race conditions in multithreaded scenarios (specifying LazyThreadSafetyMode.ExecutionAndPublication for mode), see the Lazy<T>() constructor.

例では、定義、LargeObjectクラスの複数のスレッドのいずれかによって遅れて初期化されます。The example defines a LargeObject class that will be initialized lazily by any of several threads. 初期化子、実際の初期化とコンス トラクターの作成とファイナライザーのコードの 3 つの重要なセクションを示しています、LargeObjectクラス。The three key sections of code illustrate the creation of the initializer, the actual initialization, and the constructor and finalizer of the LargeObject class. 先頭に、Mainメソッドの例は、作成、Lazy<T>の遅延初期化を実行するオブジェクト、 LargeObject:At the beginning of the Main method, the example creates the Lazy<T> object that performs lazy initialization of the LargeObject:

lazyLargeObject = new Lazy<LargeObject>(LazyThreadSafetyMode.PublicationOnly);
lazyLargeObject = New Lazy(Of LargeObject)(LazyThreadSafetyMode.PublicationOnly)

例を作成し、ブロックの 3 つのスレッドを開始、ManualResetEventオブジェクトの例が、スレッドをすべて同時に解放できるようにします。The example creates and starts three threads that block on a ManualResetEvent object, so that the example can release the threads all at once. ThreadProcメソッドを呼び出す 3 つすべてのスレッドで使用される、Valueプロパティでは、LargeObjectインスタンス。In the ThreadProc method that's used by all three threads, calling the Value property creates the LargeObject instance:

LargeObject large = lazyLargeObject.Value;
Dim large As LargeObject = lazyLargeObject.Value

のコンス トラクター、Lazy<T>指定されたインスタンスLazyThreadSafetyMode.PublicationOnly、3 つすべてのスレッドの作成を許可LargeObjectインスタンス。Because the constructor for the Lazy<T> instance specified LazyThreadSafetyMode.PublicationOnly, all three threads are allowed to create LargeObject instances. 例では、これを示します、コンス トラクターとファイナライザーのコンソール メッセージを表示することによって、LargeObjectクラス。The example demonstrates this by displaying console messages in the constructor and in the finalizer of the LargeObject class:

public LargeObject() 
{ 
    initBy = Thread.CurrentThread.ManagedThreadId;
    Console.WriteLine("Constructor: Instance initializing on thread {0}", initBy);
}

~LargeObject()
{
    Console.WriteLine("Finalizer: Instance was initialized on {0}", initBy);
}
Public Sub New()
    initBy = Thread.CurrentThread.ManagedThreadId
    Console.WriteLine("Constructor: Instance initializing on thread {0}", initBy)
End Sub

Protected Overrides Sub Finalize()
    Console.WriteLine("Finalizer: Instance was initialized on {0}", initBy)
End Sub

ただし、Lazy<T>オブジェクトにより 1 つのインスタンスは、すべてのスレッドによって使用されます。However, the Lazy<T> object ensures that only one instance is used by all threads. 例の出力は、次の 3 つのすべてのスレッドを使用して、同じインスタンスともその他の 2 つのインスタンスをガベージ コレクションによって解放できることを示しています、ことを示しています。The output from the example shows that all three threads use the same instance, and also shows that the other two instances can be reclaimed by garbage collection.

注意

簡略化のために、この例では Lazy<T> のグローバル インスタンスを使用して、すべてのメソッドは static (Visual Basic の Shared) です。For simplicity, this example uses a global instance of Lazy<T>, and all the methods are static (Shared in Visual Basic). これらは、遅延初期化を使用するための要件ではありません。These are not requirements for the use of lazy initialization.

using System;
using System.Threading;

class Program
{
    static Lazy<LargeObject> lazyLargeObject = null;

    static void Main()
    {
        // The lazy initializer is created here. LargeObject is not created until the 
        // ThreadProc method executes.
        lazyLargeObject = new Lazy<LargeObject>(LazyThreadSafetyMode.PublicationOnly);


        // Create and start 3 threads, passing the same blocking event to all of them.
        ManualResetEvent startingGate = new ManualResetEvent(false);
        Thread[] threads = { new Thread(ThreadProc), new Thread(ThreadProc), new Thread(ThreadProc) };
        foreach (Thread t in threads)
        {
            t.Start(startingGate);
        }

        // Give all 3 threads time to start and wait, then release them all at once.
        Thread.Sleep(50);
        startingGate.Set();

        // Wait for all 3 threads to finish. (The order doesn't matter.)
        foreach (Thread t in threads)
        {
            t.Join();
        }

        Console.WriteLine(
            "\r\nThreads are complete. Running GC.Collect() to reclaim the extra instances.");

        GC.Collect();

        // Allow time for garbage collection, which happens asynchronously.
        Thread.Sleep(100);

        Console.WriteLine( 
            "\r\nNote that all three threads used the instance that was not collected.");
        Console.WriteLine("Press Enter to end the program");
        Console.ReadLine();
    }


    static void ThreadProc(object state)
    {
        // Wait for the signal.
        ManualResetEvent waitForStart = (ManualResetEvent) state;
        waitForStart.WaitOne();

        LargeObject large = lazyLargeObject.Value;

        // The following line introduces an artificial delay, to exaggerate the race 
        // condition.
        Thread.Sleep(5); 

        // IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the  
        //            object after creation. You must lock the object before accessing it,
        //            unless the type is thread safe. (LargeObject is not thread safe.)
        lock(large)
        {
            large.Data[0] = Thread.CurrentThread.ManagedThreadId;
            Console.WriteLine("LargeObject was initialized by thread {0}; last used by thread {1}.", 
                large.InitializedBy, large.Data[0]);
        }
    }
}

class LargeObject
{
    int initBy = -1;
    public int InitializedBy { get { return initBy; } }

    public LargeObject() 
    { 
        initBy = Thread.CurrentThread.ManagedThreadId;
        Console.WriteLine("Constructor: Instance initializing on thread {0}", initBy);
    }

    ~LargeObject()
    {
        Console.WriteLine("Finalizer: Instance was initialized on {0}", initBy);
    }
    
    public long[] Data = new long[100000000];
}

/* This example produces output similar to the following:

Constructor: Instance initializing on thread 4
Constructor: Instance initializing on thread 3
Constructor: Instance initializing on thread 5
LargeObject was initialized by thread 4; last used by thread 4.
LargeObject was initialized by thread 4; last used by thread 5.
LargeObject was initialized by thread 4; last used by thread 3.

Threads are complete. Running GC.Collect() to reclaim the extra instances.
Finalizer: Instance was initialized on 3
Finalizer: Instance was initialized on 5

Note that all three threads used the instance that was not collected.
Press Enter to end the program

Instance finalizing; initialized on 4
 */
Imports System
Imports System.Threading

Friend Class Program
    Private Shared lazyLargeObject As Lazy(Of LargeObject) = Nothing

    Shared Sub Main()
        ' The lazy initializer is created here. LargeObject is not created until the 
        ' ThreadProc method executes.
        lazyLargeObject = New Lazy(Of LargeObject)(LazyThreadSafetyMode.PublicationOnly)


        ' Create and start 3 threads, passing the same blocking event to all of them.
        Dim startingGate As New ManualResetEvent(False)
        Dim threads() As Thread = { _
            New Thread(AddressOf ThreadProc), _
            New Thread(AddressOf ThreadProc), _
            New Thread(AddressOf ThreadProc) _
        }
        For Each t As Thread In threads
            t.Start(startingGate)
        Next t

        ' Give all 3 threads time to start and wait, then release them all at once.
        Thread.Sleep(50)
        startingGate.Set()

        ' Wait for all 3 threads to finish. (The order doesn't matter.)
        For Each t As Thread In threads
            t.Join()
        Next t

        Console.WriteLine(vbCrLf & _
            "Threads are complete. Running GC.Collect() to reclaim the extra instances.")

        GC.Collect()

        ' Allow time for garbage collection, which happens asynchronously.
        Thread.Sleep(100)

        Console.WriteLine(vbCrLf & _
            "Note that all three threads used the instance that was not collected.")
        Console.WriteLine("Press Enter to end the program")
        Console.ReadLine()

    End Sub


    Private Shared Sub ThreadProc(ByVal state As Object)
        ' Wait for the signal.
        Dim waitForStart As ManualResetEvent = CType(state, ManualResetEvent)
        waitForStart.WaitOne()

        Dim large As LargeObject = lazyLargeObject.Value

        ' The following line introduces an artificial delay, to exaggerate the race 
        ' condition.
        Thread.Sleep(5)

        ' IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the  
        '            object after creation. You must lock the object before accessing it,
        '            unless the type is thread safe. (LargeObject is not thread safe.)
        SyncLock large
            large.Data(0) = Thread.CurrentThread.ManagedThreadId
            Console.WriteLine( _
                "LargeObject was initialized by thread {0}; last used by thread {1}.", _
                large.InitializedBy, large.Data(0))
        End SyncLock
    End Sub
End Class

Friend Class LargeObject
    Private initBy As Integer = -1
    Public ReadOnly Property InitializedBy() As Integer
        Get
            Return initBy
        End Get
    End Property

    Public Sub New()
        initBy = Thread.CurrentThread.ManagedThreadId
        Console.WriteLine("Constructor: Instance initializing on thread {0}", initBy)
    End Sub

    Protected Overrides Sub Finalize()
        Console.WriteLine("Finalizer: Instance was initialized on {0}", initBy)
    End Sub

    Public Data(100000000) As Long
End Class

' This example produces output similar to the following:
'
'Constructor: Instance initializing on thread 3
'Constructor: Instance initializing on thread 5
'Constructor: Instance initializing on thread 4
'LargeObject was initialized by thread 3; last used by thread 4.
'LargeObject was initialized by thread 3; last used by thread 3.
'LargeObject was initialized by thread 3; last used by thread 5.
'
'Threads are complete. Running GC.Collect() to reclaim the extra instances.
'Finalizer: Instance was initialized on 5
'Finalizer: Instance was initialized on 4
'
'Note that all three threads used the instance that was not collected.
'Press Enter to end the program
'
'Finalizer: Instance was initialized on 3
' 

注釈

スレッドの安全性モード、Lazy<T>インスタンスを初期化しようとしている複数のスレッドと動作を示しています、Lazy<T>インスタンス。The thread safety mode of a Lazy<T> instance describes the behavior when multiple threads try to initialize the Lazy<T> instance.

ALazy<T>このコンス トラクターで作成されたインスタンスには、例外をキャッシュしません。A Lazy<T> instance that is created with this constructor does not cache exceptions. 詳細については、Lazy<T> クラスまたは System.Threading.LazyThreadSafetyMode 列挙体の解説を参照してください。For more information, see the Lazy<T> class or the System.Threading.LazyThreadSafetyMode enumeration.

こちらもご覧ください

Lazy<T>(T) Lazy<T>(T) Lazy<T>(T) Lazy<T>(T)

事前に初期化され、指定された値を使用する Lazy<T> クラスの新しいインスタンスを初期化します。Initializes a new instance of the Lazy<T> class that uses a preinitialized specified value.

public:
 Lazy(T value);
public Lazy (T value);
new Lazy<'T> : 'T -> Lazy<'T>
Public Sub New (value As T)

パラメーター

value
T T T T

使用される、事前に初期化された値。The preinitialized value to be used.

注釈

このコンス トラクターで作成されたインスタンスは同時に複数のスレッドで使用可能です。An instance created with this constructor is usable by multiple threads concurrently.

Lazy<T>(Func<T>, Boolean) Lazy<T>(Func<T>, Boolean) Lazy<T>(Func<T>, Boolean) Lazy<T>(Func<T>, Boolean)

Lazy<T> クラスの新しいインスタンスを初期化します。Initializes a new instance of the Lazy<T> class. 遅延初期化が発生した場合、指定された初期化関数および初期化モードが使用されます。When lazy initialization occurs, the specified initialization function and initialization mode are used.

public:
 Lazy(Func<T> ^ valueFactory, bool isThreadSafe);
public Lazy (Func<T> valueFactory, bool isThreadSafe);
new Lazy<'T> : Func<'T> * bool -> Lazy<'T>
Public Sub New (valueFactory As Func(Of T), isThreadSafe As Boolean)

パラメーター

valueFactory
Func<T>

必要時に遅延初期化される値を生成するために呼び出されるデリゲート。The delegate that is invoked to produce the lazily initialized value when it is needed.

isThreadSafe
Boolean Boolean Boolean Boolean

このインスタンスを複数のスレッドで同時に使用できるようにする場合は true。このインスタンスを一度に 1 つのスレッドでしか使用できないようにする場合は falsetrue to make this instance usable concurrently by multiple threads; false to make this instance usable by only one thread at a time.

例外

valueFactorynullです。valueFactory is null.

次の例では、例外がキャッシュには、1 つのスレッドがあるシナリオで遅延初期化を提供するこのコンス トラクターの使用を示します。The following example demonstrates the use of this constructor to provide lazy initialization with exception caching, in a scenario with a single thread. 使用にも示しますが、Lazy<T>コンス トラクター (を指定するLazyThreadSafetyMode.Nonemode)。It also demonstrates the use of the Lazy<T> constructor (specifying LazyThreadSafetyMode.None for mode). そのコンス トラクターを切り替えるだけコンス トラクターをコメント アウトを変更します。To switch to that constructor, just change which constructor is commented out.

注意

マルチ スレッド シナリオでこのコンス トラクターを使用する方法を示すコードについて (を指定するtrueisThreadSafe)、例をご覧ください、Lazy<T>(Func<T>)コンス トラクター。For code that demonstrates how to use this constructor in multithreaded scenarios (specifying true for isThreadSafe), see the example for the Lazy<T>(Func<T>) constructor.

この例では、複数あるスレッドのうちの 1 つによって遅れて初期化される LargeObject クラスを定義します。The example defines a LargeObject class that will be initialized lazily by one of several threads. コードの 3 つの主要セクションが、初期化子、実際の初期化のコンス トラクターの作成を示しています、LargeObjectクラスは、例外キャッシュを示します。The three key sections of code illustrate the creation of the initializer, the actual initialization, and the constructor of the LargeObject class, which demonstrates exception caching. Main メソッドの開始時に、この例では LargeObject のスレッドセーフな遅延初期化子が作成されます。At the beginning of the Main method, the example creates the thread-safe lazy initializer for LargeObject:

lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, false);

// The following lines show how to use other constructors to achieve exactly the
// same result as the previous line: 
//lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, LazyThreadSafetyMode.None);
lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, False)

' The following lines show how to use other constructors to achieve exactly the
' same result as the previous line: 
'lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, LazyThreadSafetyMode.None)

コンス トラクターの呼び出しで、isThreadSafeパラメーターがfalseであり、Lazy<T>安全なスレッドはありません。In the call to the constructor, the isThreadSafe parameter is false, so the Lazy<T> is not thread safe. 例ではスレッド セーフではないため、 Value 3 回、同じスレッドでのプロパティ。Because it's not thread safe, the example calls the Value property three times on the same thread:

for (int i = 0; i < 3; i++)
{
    try
    {
        LargeObject large = lazyLargeObject.Value;
        large.Data[11] = 89;
    }
    catch (ApplicationException aex)
    {
        Console.WriteLine("Exception: {0}", aex.Message);
    }
}
For i As Integer = 0 To 2
    Try
        Dim large As LargeObject = lazyLargeObject.Value
        large.Data(11) = 89
    Catch aex As ApplicationException
        Console.WriteLine("Exception: {0}", aex.Message)
    End Try
Next i

コンス トラクター、LargeObjectクラス、コードの 3 番目のキー セクションが最初に例外をスロー、LargeObjectインスタンスが作成されますが、発生するインスタンスの作成は、その後。In the constructor of the LargeObject class, the third key section of code throws an exception the first time a LargeObject instance is created, but thereafter allows instance creation to occur:

static bool pleaseThrow = true;
public LargeObject()
{
    if (pleaseThrow)
    {
        pleaseThrow = false;
        throw new ApplicationException("Throw only ONCE.");
    }

    Console.WriteLine("LargeObject was created on thread id {0}.", 
        Thread.CurrentThread.ManagedThreadId);
}
Private Shared pleaseThrow As Boolean = True
Public Sub New()
    If pleaseThrow Then
        pleaseThrow = False
        Throw New ApplicationException("Throw only ONCE.")
    End If

    Console.WriteLine("LargeObject was created on thread id {0}.", _
        Thread.CurrentThread.ManagedThreadId)
End Sub

例では、実行時のインスタンスを作成する最初の試みLargeObject失敗し、例外がキャッチされます。When the example is run, the first attempt to create an instance of LargeObject fails, and the exception is caught. 次の試行が成功すると思うかもしれませんが、Lazy<T>オブジェクトが例外をキャッシュします。You might expect that the next attempt would succeed, but the Lazy<T> object has cached the exception. このため、次の 3 つのすべての試行は、例外をスローします。Because of this, all three attempts throw the exception.

注意

簡略化のために、この例では Lazy<T> のグローバル インスタンスを使用して、すべてのメソッドは static (Visual Basic の Shared) です。For simplicity, this example uses a global instance of Lazy<T>, and all the methods are static (Shared in Visual Basic). これらは、遅延初期化を使用するための要件ではありません。These are not requirements for the use of lazy initialization.

using System;
using System.Threading;

class Program
{
    static Lazy<LargeObject> lazyLargeObject = null;

    static LargeObject InitLargeObject()
    {
        return new LargeObject();
    }


    static void Main()
    {
        // The lazy initializer is created here. LargeObject is not created until the 
        // ThreadProc method executes.
        lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, false);

        // The following lines show how to use other constructors to achieve exactly the
        // same result as the previous line: 
        //lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, LazyThreadSafetyMode.None);


        Console.WriteLine(
            "\r\nLargeObject is not created until you access the Value property of the lazy" +
            "\r\ninitializer. Press Enter to create LargeObject (three tries).");
        Console.ReadLine();

        for (int i = 0; i < 3; i++)
        {
            try
            {
                LargeObject large = lazyLargeObject.Value;
                large.Data[11] = 89;
            }
            catch (ApplicationException aex)
            {
                Console.WriteLine("Exception: {0}", aex.Message);
            }
        }

        Console.WriteLine("\r\nPress Enter to end the program");
        Console.ReadLine();
    }
}

class LargeObject
{
    static bool pleaseThrow = true;
    public LargeObject()
    {
        if (pleaseThrow)
        {
            pleaseThrow = false;
            throw new ApplicationException("Throw only ONCE.");
        }

        Console.WriteLine("LargeObject was created on thread id {0}.", 
            Thread.CurrentThread.ManagedThreadId);
    }
    public long[] Data = new long[100000000];
}

/* This example produces output similar to the following:

LargeObject is not created until you access the Value property of the lazy
initializer. Press Enter to create LargeObject (three tries).

Exception: Throw only ONCE.
Exception: Throw only ONCE.
Exception: Throw only ONCE.

Press Enter to end the program
 */
Imports System
Imports System.Threading

Friend Class Program
    Private Shared lazyLargeObject As Lazy(Of LargeObject) = Nothing

    Private Shared Function InitLargeObject() As LargeObject
        Return New LargeObject()
    End Function


    Shared Sub Main()
        ' The lazy initializer is created here. LargeObject is not created until the 
        ' ThreadProc method executes.
        lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, False)

        ' The following lines show how to use other constructors to achieve exactly the
        ' same result as the previous line: 
        'lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, LazyThreadSafetyMode.None)


        Console.WriteLine(vbCrLf _
            & "LargeObject is not created until you access the Value property of the lazy" _
            & vbCrLf & "initializer. Press Enter to create LargeObject (three tries).")
        Console.ReadLine()

        For i As Integer = 0 To 2
            Try
                Dim large As LargeObject = lazyLargeObject.Value
                large.Data(11) = 89
            Catch aex As ApplicationException
                Console.WriteLine("Exception: {0}", aex.Message)
            End Try
        Next i

        Console.WriteLine(vbCrLf & "Press Enter to end the program")
        Console.ReadLine()
    End Sub
End Class

Friend Class LargeObject
    Private Shared pleaseThrow As Boolean = True
    Public Sub New()
        If pleaseThrow Then
            pleaseThrow = False
            Throw New ApplicationException("Throw only ONCE.")
        End If

        Console.WriteLine("LargeObject was created on thread id {0}.", _
            Thread.CurrentThread.ManagedThreadId)
    End Sub
    Public Data(100000000) As Long
End Class

' This example produces output similar to the following:
'
'LargeObject is not created until you access the Value property of the lazy
'initializer. Press Enter to create LargeObject (three tries).
'
'Exception: Throw only ONCE.
'Exception: Throw only ONCE.
'Exception: Throw only ONCE.
'
'Press Enter to end the program
' 

注釈

スレッドの安全性モード、Lazy<T>このコンス トラクターで初期化されたインスタンスがLazyThreadSafetyMode.ExecutionAndPublication場合isThreadSafetrue、それ以外のモードはLazyThreadSafetyMode.Noneします。The thread safety mode of a Lazy<T> instance that is initialized with this constructor is LazyThreadSafetyMode.ExecutionAndPublication if isThreadSafe is true; otherwise, the mode is LazyThreadSafetyMode.None. 初期化しようとしている複数のスレッドとスレッドの安全性モードは、動作について説明します、Lazy<T>インスタンス。The thread safety mode describes the behavior when multiple threads try to initialize the Lazy<T> instance.

指定する、LazyThreadSafetyMode.PublicationOnlyモードを使用して、Lazy<T>(Func<T>, LazyThreadSafetyMode)またはLazy<T>(LazyThreadSafetyMode)コンス トラクター。To specify the LazyThreadSafetyMode.PublicationOnly mode, use the Lazy<T>(Func<T>, LazyThreadSafetyMode) or Lazy<T>(LazyThreadSafetyMode) constructor.

によってスローされる例外valueFactoryキャッシュされます。Exceptions that are thrown by valueFactory are cached. 詳細については、Lazy<T> クラスまたは System.Threading.LazyThreadSafetyMode 列挙体の解説を参照してください。For more information, see the Lazy<T> class or the System.Threading.LazyThreadSafetyMode enumeration.

こちらもご覧ください

Lazy<T>(Func<T>, LazyThreadSafetyMode) Lazy<T>(Func<T>, LazyThreadSafetyMode) Lazy<T>(Func<T>, LazyThreadSafetyMode) Lazy<T>(Func<T>, LazyThreadSafetyMode)

指定された初期化関数とスレッド セーフ モードを使用する Lazy<T> クラスの新しいインスタンスを初期化します。Initializes a new instance of the Lazy<T> class that uses the specified initialization function and thread-safety mode.

public:
 Lazy(Func<T> ^ valueFactory, System::Threading::LazyThreadSafetyMode mode);
public Lazy (Func<T> valueFactory, System.Threading.LazyThreadSafetyMode mode);
new Lazy<'T> : Func<'T> * System.Threading.LazyThreadSafetyMode -> Lazy<'T>
Public Sub New (valueFactory As Func(Of T), mode As LazyThreadSafetyMode)

パラメーター

valueFactory
Func<T>

必要時に遅延初期化される値を生成するために呼び出されるデリゲート。The delegate that is invoked to produce the lazily initialized value when it is needed.

mode
LazyThreadSafetyMode LazyThreadSafetyMode LazyThreadSafetyMode LazyThreadSafetyMode

スレッド セーフ モードを指定する列挙値の 1 つ。One of the enumeration values that specifies the thread safety mode.

例外

mode に無効な値が含まれています。mode contains an invalid value.

valueFactorynullです。valueFactory is null.

次の例では、複数のスレッドが競合するオブジェクトの遅延作成を遅延初期化子を作成するこのコンス トラクターの使用を示します。The following example demonstrates the use of this constructor to create a lazy initializer that enables multiple threads to race to create an object lazily. 複数のスレッドが、インスタンスの作成に成功可能性がありますが、すべてのスレッドが最初に作成されたインスタンスを使用します。Multiple threads might succeed in creating instances, but all threads use the instance that was created first. さらに、例を示しますを指定するときに例外がキャッシュされないLazyThreadSafetyMode.PublicationOnlyは限定的に作成された型の既定のコンス トラクターで、初期化がの代わりに関数によって実行される場合でも、します。In addition, the example demonstrates that exceptions are never cached when you specify LazyThreadSafetyMode.PublicationOnly, even if initialization is performed by a function instead of by the default constructor of the lazily created type.

注意

シングル スレッド シナリオでこのコンス トラクターを使用する方法を示す例については (を指定するLazyThreadSafetyMode.Nonemode) を参照してください、Lazy<T>(Boolean)コンス トラクター。For an example that demonstrates how to use this constructor in single-threaded scenarios (specifying LazyThreadSafetyMode.None for mode), see the Lazy<T>(Boolean) constructor. このコンス トラクターを使用して、競合状態がマルチ スレッド シナリオではなく、ロックを提供する方法を示す例については (を指定するLazyThreadSafetyMode.ExecutionAndPublicationmode) を参照してください、Lazy<T>()コンス トラクター。For an example that demonstrates how to use this constructor to provide locking instead of race conditions in multithreaded scenarios (specifying LazyThreadSafetyMode.ExecutionAndPublication for mode), see the Lazy<T>() constructor.

例では、定義、LargeObjectクラスの複数のスレッドのいずれかによって遅れて初期化されます。The example defines a LargeObject class that will be initialized lazily by any of several threads. 初期化子、実際の初期化、初期化関数、および、コンス トラクターの作成とファイナライザーのコードの 4 つの重要なセクションを示しています、LargeObjectクラス。The four key sections of code illustrate the creation of the initializer, the actual initialization, the initialization function, and the constructor and finalizer of the LargeObject class. 先頭に、Mainメソッドの例は、作成、Lazy<T>の遅延初期化を実行するオブジェクト、 LargeObject:At the beginning of the Main method, the example creates the Lazy<T> object that performs lazy initialization of the LargeObject:

lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, 
                             LazyThreadSafetyMode.PublicationOnly);
lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, _
     LazyThreadSafetyMode.PublicationOnly)

遅延初期化子では、関数を使用して、初期化を実行します。The lazy initializer uses a function to perform the initialization. この場合、関数が必要なの既定のコンス トラクターはありません、LargeObjectクラス。In this case, a function is required because there is no default constructor for the LargeObject class.

例を作成し、ブロックの 3 つのスレッドを開始、ManualResetEventオブジェクトの例が、スレッドをすべて同時に解放できるようにします。The example creates and starts three threads that block on a ManualResetEvent object, so that the example can release the threads all at once. ThreadProcメソッドを呼び出す 3 つすべてのスレッドで使用される、Valueプロパティでは、LargeObjectインスタンス。In the ThreadProc method that's used by all three threads, calling the Value property creates the LargeObject instance:

LargeObject large = null;
try
{
    large = lazyLargeObject.Value;

    // The following line introduces an artificial delay, to exaggerate the race 
    // condition.
    Thread.Sleep(5); 

    // IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the  
    //            object after creation. You must lock the object before accessing it,
    //            unless the type is thread safe. (LargeObject is not thread safe.)
    lock(large)
    {
        large.Data[0] = Thread.CurrentThread.ManagedThreadId;
        Console.WriteLine("LargeObject was initialized by thread {0}; last used by thread {1}.", 
            large.InitializedBy, large.Data[0]);
    }
}
catch (ApplicationException ex)
{
    Console.WriteLine("ApplicationException: {0}", ex.Message);
}
Dim large As LargeObject = Nothing
Try
    large = lazyLargeObject.Value

    ' The following line introduces an artificial delay, to exaggerate the race 
    ' condition.
    Thread.Sleep(5)

    ' IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the  
    '            object after creation. You must lock the object before accessing it,
    '            unless the type is thread safe. (LargeObject is not thread safe.)
    SyncLock large
        large.Data(0) = Thread.CurrentThread.ManagedThreadId
        Console.WriteLine( _
            "LargeObject was initialized by thread {0}; last used by thread {1}.", _
            large.InitializedBy, large.Data(0))
    End SyncLock
Catch ex As ApplicationException
    Console.WriteLine("ApplicationException: {0}", ex.Message)
End Try

遅延初期化関数の呼び出しを作成するコードの 3 番目のキーのセクションで、LargeObjectインスタンス。In the third key section of code, the lazy initialization function is called to create the LargeObject instance. 関数が呼び出される例外は、最初にスローされます。The function throws an exception the first time it's called:

static int instanceCount = 0;
static LargeObject InitLargeObject()
{
    if (1 == Interlocked.Increment(ref instanceCount))
    {
        throw new ApplicationException(
            String.Format("Lazy initialization function failed on thread {0}.",
            Thread.CurrentThread.ManagedThreadId));
    }
    return new LargeObject(Thread.CurrentThread.ManagedThreadId);
}
Private Shared instanceCount As Integer = 0
Private Shared Function InitLargeObject() As LargeObject
    If 1 = Interlocked.Increment(instanceCount) Then
        Throw New ApplicationException( _
            "Lazy initialization function failed on thread " & _
            Thread.CurrentThread.ManagedThreadId & ".")
    End If
    Return New LargeObject(Thread.CurrentThread.ManagedThreadId)
End Function

その他のLazyThreadSafetyMode設定すると、初期化関数で未処理の例外はキャッシュされます。With any other LazyThreadSafetyMode setting, an unhandled exception in the initialization function would be cached. ただし、LazyThreadSafetyMode.PublicationOnly例外キャッシュを抑制します。However, LazyThreadSafetyMode.PublicationOnly suppresses exception caching. 例の出力では、オブジェクトを初期化する後続の試行が成功したことを示します。The output from the example demonstrates that a subsequent attempt to initialize the object succeeds.

注意

通常、例外メッセージは、後は、他のスレッドがオブジェクトを正常に初期化があることを示すメッセージが表示されます。The exception message usually appears after messages indicating that other threads have successfully initialized the object. これは、スローされると、例外をキャッチするで導入された、遅延が原因です。This is because of the delay introduced by throwing and catching the exception.

のコンス トラクター、Lazy<T>指定されたインスタンスLazyThreadSafetyMode.PublicationOnly、3 つすべてのスレッドの作成を許可LargeObjectインスタンス。Because the constructor for the Lazy<T> instance specified LazyThreadSafetyMode.PublicationOnly, all three threads are allowed to create LargeObject instances. 例では、これを示します、コンス トラクターとファイナライザーのコンソール メッセージを表示することによって、LargeObjectクラス。The example demonstrates this by displaying console messages in the constructor and in the finalizer of the LargeObject class:

public LargeObject(int initializedBy) 
{ 
    initBy = initializedBy;
    Console.WriteLine("Constructor: Instance initializing on thread {0}", initBy);
}

~LargeObject()
{
    Console.WriteLine("Finalizer: Instance was initialized on {0}", initBy);
}
Public Sub New(ByVal initializedBy As Integer)
    initBy = initializedBy
    Console.WriteLine("Constructor: Instance initializing on thread {0}", initBy)
End Sub

Protected Overrides Sub Finalize()
    Console.WriteLine("Finalizer: Instance was initialized on {0}", initBy)
End Sub

Lazy<T>オブジェクトにより、スレッドの初期化関数が例外をスローします) (を除くすべてのスレッドによって 1 つのインスタンスが使用されるようになります。The Lazy<T> object ensures that only one instance is used by all threads (except the thread where the initialization function throws an exception). この例の出力を示します。The output from the example shows this.

注意

簡略化のために、この例では Lazy<T> のグローバル インスタンスを使用して、すべてのメソッドは static (Visual Basic の Shared) です。For simplicity, this example uses a global instance of Lazy<T>, and all the methods are static (Shared in Visual Basic). これらは、遅延初期化を使用するための要件ではありません。These are not requirements for the use of lazy initialization.

using System;
using System.Threading;

class Program
{
    static Lazy<LargeObject> lazyLargeObject = null;

    // Factory function for lazy initialization.
    static int instanceCount = 0;
    static LargeObject InitLargeObject()
    {
        if (1 == Interlocked.Increment(ref instanceCount))
        {
            throw new ApplicationException(
                String.Format("Lazy initialization function failed on thread {0}.",
                Thread.CurrentThread.ManagedThreadId));
        }
        return new LargeObject(Thread.CurrentThread.ManagedThreadId);
    }

    static void Main()
    {
        // The lazy initializer is created here. LargeObject is not created until the 
        // ThreadProc method executes.
        lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, 
                                     LazyThreadSafetyMode.PublicationOnly);


        // Create and start 3 threads, passing the same blocking event to all of them.
        ManualResetEvent startingGate = new ManualResetEvent(false);
        Thread[] threads = { new Thread(ThreadProc), new Thread(ThreadProc), new Thread(ThreadProc) };
        foreach (Thread t in threads)
        {
            t.Start(startingGate);
        }

        // Give all 3 threads time to start and wait, then release them all at once.
        Thread.Sleep(50);
        startingGate.Set();

        // Wait for all 3 threads to finish. (The order doesn't matter.)
        foreach (Thread t in threads)
        {
            t.Join();
        }

        Console.WriteLine(
            "\r\nThreads are complete. Running GC.Collect() to reclaim extra instances.");

        GC.Collect();

        // Allow time for garbage collection, which happens asynchronously.
        Thread.Sleep(100);

        Console.WriteLine("\r\nNote that only one instance of LargeObject was used.");
        Console.WriteLine("Press Enter to end the program");
        Console.ReadLine();
    }


    static void ThreadProc(object state)
    {
        // Wait for the signal.
        ManualResetEvent waitForStart = (ManualResetEvent) state;
        waitForStart.WaitOne();

        LargeObject large = null;
        try
        {
            large = lazyLargeObject.Value;

            // The following line introduces an artificial delay, to exaggerate the race 
            // condition.
            Thread.Sleep(5); 

            // IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the  
            //            object after creation. You must lock the object before accessing it,
            //            unless the type is thread safe. (LargeObject is not thread safe.)
            lock(large)
            {
                large.Data[0] = Thread.CurrentThread.ManagedThreadId;
                Console.WriteLine("LargeObject was initialized by thread {0}; last used by thread {1}.", 
                    large.InitializedBy, large.Data[0]);
            }
        }
        catch (ApplicationException ex)
        {
            Console.WriteLine("ApplicationException: {0}", ex.Message);
        }
    }
}

class LargeObject
{
    int initBy = -1;
    public int InitializedBy { get { return initBy; } }

    public LargeObject(int initializedBy) 
    { 
        initBy = initializedBy;
        Console.WriteLine("Constructor: Instance initializing on thread {0}", initBy);
    }

    ~LargeObject()
    {
        Console.WriteLine("Finalizer: Instance was initialized on {0}", initBy);
    }
    
    public long[] Data = new long[100000000];
}

/* This example produces output similar to the following:

Constructor: Instance initializing on thread 5
Constructor: Instance initializing on thread 4
ApplicationException: Lazy initialization function failed on thread 3.
LargeObject was initialized by thread 5; last used by thread 5.
LargeObject was initialized by thread 5; last used by thread 4.

Threads are complete. Running GC.Collect() to reclaim extra instances.
Finalizer: Instance was initialized on 4

Note that only one instance of LargeObject was used.
Press Enter to end the program

Finalizer: Instance was initialized on 5
 */
Imports System
Imports System.Threading

Friend Class Program
    Private Shared lazyLargeObject As Lazy(Of LargeObject) = Nothing

    ' Factory function for lazy initialization.
    Private Shared instanceCount As Integer = 0
    Private Shared Function InitLargeObject() As LargeObject
        If 1 = Interlocked.Increment(instanceCount) Then
            Throw New ApplicationException( _
                "Lazy initialization function failed on thread " & _
                Thread.CurrentThread.ManagedThreadId & ".")
        End If
        Return New LargeObject(Thread.CurrentThread.ManagedThreadId)
    End Function

    Shared Sub Main()
        ' The lazy initializer is created here. LargeObject is not created until the 
        ' ThreadProc method executes.
        lazyLargeObject = New Lazy(Of LargeObject)(AddressOf InitLargeObject, _
             LazyThreadSafetyMode.PublicationOnly)


        ' Create and start 3 threads, passing the same blocking event to all of them.
        Dim startingGate As New ManualResetEvent(False)
        Dim threads() As Thread = { _
            New Thread(AddressOf ThreadProc), _
            New Thread(AddressOf ThreadProc), _
            New Thread(AddressOf ThreadProc) _
        }
        For Each t As Thread In threads
            t.Start(startingGate)
        Next t

        ' Give all 3 threads time to start and wait, then release them all at once.
        Thread.Sleep(50)
        startingGate.Set()

        ' Wait for all 3 threads to finish. (The order doesn't matter.)
        For Each t As Thread In threads
            t.Join()
        Next t

        Console.WriteLine(vbCrLf & _
            "Threads are complete. Running GC.Collect() to reclaim extra instances.")

        GC.Collect()

        ' Allow time for garbage collection, which happens asynchronously.
        Thread.Sleep(100)

        Console.WriteLine(vbCrLf & "Note that only one instance of LargeObject was used.")
        Console.WriteLine("Press Enter to end the program")
        Console.ReadLine()
    End Sub


    Private Shared Sub ThreadProc(ByVal state As Object)
        ' Wait for the signal.
        Dim waitForStart As ManualResetEvent = CType(state, ManualResetEvent)
        waitForStart.WaitOne()

        Dim large As LargeObject = Nothing
        Try
            large = lazyLargeObject.Value

            ' The following line introduces an artificial delay, to exaggerate the race 
            ' condition.
            Thread.Sleep(5)

            ' IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the  
            '            object after creation. You must lock the object before accessing it,
            '            unless the type is thread safe. (LargeObject is not thread safe.)
            SyncLock large
                large.Data(0) = Thread.CurrentThread.ManagedThreadId
                Console.WriteLine( _
                    "LargeObject was initialized by thread {0}; last used by thread {1}.", _
                    large.InitializedBy, large.Data(0))
            End SyncLock
        Catch ex As ApplicationException
            Console.WriteLine("ApplicationException: {0}", ex.Message)
        End Try
    End Sub
End Class

Friend Class LargeObject
    Private initBy As Integer = -1
    Public ReadOnly Property InitializedBy() As Integer
        Get
            Return initBy
        End Get
    End Property

    Public Sub New(ByVal initializedBy As Integer)
        initBy = initializedBy
        Console.WriteLine("Constructor: Instance initializing on thread {0}", initBy)
    End Sub

    Protected Overrides Sub Finalize()
        Console.WriteLine("Finalizer: Instance was initialized on {0}", initBy)
    End Sub

    Public Data(99999999) As Long
End Class

' This example produces output similar to the following:
'
'Constructor: Instance initializing on thread 4
'ApplicationException: Lazy initialization function failed on thread 3.
'Constructor: Instance initializing on thread 5
'LargeObject was initialized by thread 4; last used by thread 4.
'LargeObject was initialized by thread 4; last used by thread 5.
'
'Threads are complete. Running GC.Collect() to reclaim extra instances.
'Finalizer: Instance was initialized on 5
'
'Note that only one instance of LargeObject was used.
'Press Enter to end the program
'
'Finalizer: Instance was initialized on 4
' 

注釈

スレッドの安全性モード、Lazy<T>インスタンスを初期化しようとしている複数のスレッドと動作を示しています、Lazy<T>インスタンス。The thread safety mode of a Lazy<T> instance describes the behavior when multiple threads try to initialize the Lazy<T> instance.

によってスローされる例外valueFactoryキャッシュされる場合を除き、modeLazyThreadSafetyMode.PublicationOnlyします。Exceptions that are thrown by valueFactory are cached, unless mode is LazyThreadSafetyMode.PublicationOnly. 詳細については、Lazy<T> クラスまたは System.Threading.LazyThreadSafetyMode 列挙体の解説を参照してください。For more information, see the Lazy<T> class or the System.Threading.LazyThreadSafetyMode enumeration.

こちらもご覧ください

適用対象