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;
}
}
In this example:
We define a
Singleton
class with a private constructor to prevent direct instantiation.We use
Lazy<Task<Singleton>>
for asynchronous initialization. TheInstanceAsync
method returns aTask<Singleton>
representing the Singleton instance. Theasync
lambda insidelazyInstance
is responsible for initializing the Singleton asynchronously.In the
InitializeAsync
method, we simulate asynchronous initialization (e.g., establishing a database connection) withawait Task.Delay(1000)
.In the
Main
method, we asynchronously access the Singleton usingawait 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)