DEV Community

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

Posted on

3

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.

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay