I add a singleton like this.
In Startup.cs, I add the following:
services.AddSingleton<MySingleton>();
I want to build my singleton like this (which is not possible of course):
public class MySingleton
{
public MySingleton()
{
await InitAsync();
}
private async Task InitAsync()
{
await Stuff();
}
}
How can I solve this problem without creating deadlocks?
As far as I can tell, configuration in ASP.NET Core is not asynchronous, so there is no way to add a service with async factory, or anything like that.
Because of that and considering that blocking is not a big issue if it's only done once when application starts, I think you should block when creating the service. And since ASP.NET Core does not have a synchronization context, this will also not cause a deadlock.
Use the Microsoft.VisualStudio.Threading NuGet package and then design your class like this:
public class Singleton {
private static readonly AsyncLazy<Singleton> instance =
new AsyncLazy<Singleton>( CreateAndDoSomething );
private Singleton() {
}
// This method could also be an async lambda passed to the AsyncLazy constructor.
private static async Task<Singleton> CreateAndDoSomething() {
var ret = new Singleton();
await ret.InitAsync();
return ret;
}
private async Task InitAsync() {
await Stuff();
}
public static AsyncLazy<Singleton> Instance
{
get { return instance; }
}
}
Usage:
Singleton singleton = Singleton.Instance;
More on Asynchronous Lazy Initialization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With