Lazy(Of T) Constructor (Func(Of T), Boolean)

 
System_CAPS_noteNote

The .NET API Reference documentation has a new home. Visit the .NET API Browser on docs.microsoft.com to see the new experience.

Initializes a new instance of the Lazy(Of T) class. When lazy initialization occurs, the specified initialization function and initialization mode are used.

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

Public Sub New (
	valueFactory As Func(Of T),
	isThreadSafe As Boolean
)

Parameters

valueFactory
Type: System.Func(Of T)

The delegate that is invoked to produce the lazily initialized value when it is needed.

isThreadSafe
Type: System.Boolean

true to make this instance usable concurrently by multiple threads; false to make this instance usable by only one thread at a time.

Exception Condition
ArgumentNullException

valueFactory is null.

The thread safety mode of a Lazy(Of T) instance that is initialized with this constructor is LazyThreadSafetyMode.ExecutionAndPublication if isThreadSafe is true; otherwise, the mode is LazyThreadSafetyMode.None. The thread safety mode describes the behavior when multiple threads try to initialize the Lazy(Of T) instance.

To specify the LazyThreadSafetyMode.PublicationOnly mode, use the Lazy(Of T)(Func(Of T), LazyThreadSafetyMode) or Lazy(Of T)(LazyThreadSafetyMode) constructor.

Exceptions that are thrown by valueFactory are cached. For more information, see the Lazy(Of T) class or the System.Threading.LazyThreadSafetyMode enumeration.

The following example demonstrates the use of this constructor to provide lazy initialization with exception caching, in a scenario with a single thread. It also demonstrates the use of the Lazy(Of T)constructor (specifying LazyThreadSafetyMode.None for mode). To switch to that constructor, just change which constructor is commented out.

System_CAPS_noteNote

For code that demonstrates how to use this constructor in multithreaded scenarios (specifying true for isThreadSafe), see the example for the Lazy(Of T)(Func(Of T)) constructor.

The example defines a LargeObject class that will be initialized lazily by one of several threads. 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. At the beginning of the Main method, the example creates the thread-safe lazy initializer for LargeObject:

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)

In the call to the constructor, the isThreadSafe parameter is false, so the Lazy(Of T) is not thread safe. Because it's not thread safe, the example calls the Value property three times on the same thread:

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

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:

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

When the example is run, the first attempt to create an instance of LargeObject fails, and the exception is caught. You might expect that the next attempt would succeed, but the Lazy(Of T) object has cached the exception. Because of this, all three attempts throw the exception.

System_CAPS_noteNote

For simplicity, this example uses a global instance of Lazy(Of T), and all the methods are static (Shared in Visual Basic). These are not requirements for the use of lazy initialization.

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
' 

Universal Windows Platform
Available since 8
.NET Framework
Available since 4.0
Portable Class Library
Supported in: portable .NET platforms
Silverlight
Available since 4.0
Windows Phone Silverlight
Available since 8.0
Windows Phone
Available since 8.1
Return to top
Show: