I have a Singleton Class which loads some data on its construction. The problem is that loading this data requires calling async methods, but the constructor cannot be async.
In other words, my class has following structure:
public class Singleton
{
private static Singleton instance;
private Singleton()
{
LoadData();
}
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
LoadData() is an async function which calls lots of async functions as well as initialization.
How can I call LoadData() properly so everything initialize correctly?
While you can’t make the constructor itself asynchronous, you can call asynchronous methods from within the constructor. You just will not get the results back immediately.
Provided the asynchronous methods return
TaskorTask<T>, you can always use a continuation on the task to set your data within the class once the asynchronous operation completes, or just block on the results, depending on what makes the most sense in your scenario. Without knowing the requirements for construction of this object, it’s difficult to know what is appropriate in this scenario.Edit:
One option, given the goals listed above, would be to change your
Singletondeclaration so that method to retrieve theInstancewas a method, not a property. This would allow you to make it asynchronous:This would allow you to use
awaiton the call to actually retrieve the instance. The nice thing about this is that it does make it very clear that you’re calling an asynchronous operation, and you will get proper handling of the results, as the result will come back like any other async method.Be aware, however, that this isn’t thread safe (though the original wasn’t either), so if you’re going to use this Singleton from multiple threads, you may have to rethink the overall design.
The other option would be to make your
Singletonclass not automatically load data. Make the methods that retrieve the data from the class asynchronous, instead. This provides some real advantages, as the usage is probably a bit more standard, and you can support calls from multiple threads a bit more easily (since you can control the data loading process) than you’d be able to handle it with making the access of the class instance asynchronous.