Skip to content
Ken Dale
Go back

Thread Safe Lazy Initialization Using C# Notes

Sometimes it makes sense to lazily initialize something in an application. In the case of an application internal cache waiting until the first access of data to prime the cache could improve startup times. One way of lazy initialization with C# is Lazy<T>.

Lazy<T>

Per https://learn.microsoft.com/en-us/dotnet/api/system.lazy-1#thread-safety the default is thread safe, but can be disabled. If you don’t opt-out it’s thread safe.

using System;

public class Program
{
    public static void Main()
    {
        // Uses LazyThreadSafetyMode.ExecutionAndPublication
        // See https://github.com/dotnet/corefx/blob/b8b81a66738bb10ef0790023598396861d92b2c4/src/Common/src/CoreLib/System/Lazy.cs#L240
        var lazyString = new Lazy<string>(() => "abc");

        Console.WriteLine(lazyString.Value); // abc
    }
}

Thread safety can be adjusted like

var lazyString = new Lazy<string>(() => "abc", isThreadSafe: false);

Or:

// Add:
// using System.Threading;

var lazyString1 = new Lazy<string>(() => "abc", LazyThreadSafetyMode.None);
var lazyString2 = new Lazy<string>(() => "abc", LazyThreadSafetyMode.PublicationOnly);

LazyThreadSafetyMode

Different LazyThreadSafetyMode values have characteristics you may be interested in:

Exceptions

In some cases an unhandled exception in the lazy initialization code will also cache returning an exception. See https://learn.microsoft.com/en-us/dotnet/framework/performance/lazy-initialization#exceptions-in-lazy-objects which contains a table describing when this occurs.

Additional info

If you’re looking to explore further try these docs pages:


Share this post:

Previous Post
Limiting Concurrent Operations With SemaphoreSlim Using C#
Next Post
Troubleshooting Private NuGet Packages With dotnet CLI