DEV Community

Cover image for C# - Asynchronous Initialization of Singleton Pattern
Keyur Ramoliya
Keyur Ramoliya

Posted on

C# - Asynchronous Initialization of Singleton Pattern

In scenarios where you need to initialize a Singleton instance asynchronously (e.g., database connection, network setup), you can use async and Lazy<T> to ensure that the initialization occurs only when the Singleton is first accessed.

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var singleton = await Singleton.InstanceAsync();

        Console.WriteLine($"Singleton instance created at {singleton.CreationTime}");
    }
}

class Singleton
{
    private static readonly Lazy<Task<Singleton>> lazyInstance = new Lazy<Task<Singleton>>(async () =>
    {
        var instance = new Singleton();
        await instance.InitializeAsync();
        return instance;
    });

    public DateTime CreationTime { get; private set; }

    private Singleton()
    {
        // Private constructor to prevent direct instantiation.
    }

    public static Task<Singleton> InstanceAsync()
    {
        return lazyInstance.Value;
    }

    private async Task InitializeAsync()
    {
        // Simulate asynchronous initialization (e.g., database connection)
        await Task.Delay(1000);
        CreationTime = DateTime.Now;
    }
}
Enter fullscreen mode Exit fullscreen mode

In this example:

  1. We define a Singleton class with a private constructor to prevent direct instantiation.

  2. We use Lazy<Task<Singleton>> for asynchronous initialization. The InstanceAsync method returns a Task<Singleton> representing the Singleton instance. The async lambda inside lazyInstance is responsible for initializing the Singleton asynchronously.

  3. In the InitializeAsync method, we simulate asynchronous initialization (e.g., establishing a database connection) with await Task.Delay(1000).

  4. In the Main method, we asynchronously access the Singleton using await Singleton.InstanceAsync(), ensuring that the Singleton is initialized only when it is first accessed.

Using this approach, you can ensure that your Singleton instances are created asynchronously, allowing you to perform complex initialization tasks without blocking the calling code. This is particularly useful for scenarios where the initialization process may involve I/O operations or other time-consuming tasks.

Top comments (0)