Post

Thread Safe Lazy Initialization Using C# Notes

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
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

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

Or:

1
2
3
4
5
// 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:

  • LazyThreadSafetyMode.ExecutionAndPublication can deadlock if the initialization code has locks internally. It is also the default value.
  • LazyThreadSafetyMode.None can help for high performance scenarios when there’s a guarantee it won’t be called simultaneously by multiple threads.
  • LazyThreadSafetyMode.Publication allows multiple executions of the initialization code by multiple threads. The first thread to complete the initialization code sets the value.

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:

This post is licensed under CC BY 4.0 by the author.