You can't have an async
constructor, period.
So whatever you do, you'll need to handle the situation where your constructor returns without having completed its async
initialization.
There are a few ways of handling this. If the "steps" are loading resources, then you can do something like this (using the AsyncLazy
type from my blog, Stephen Toub's blog, or my AsyncEx library - they're all nearly the same):
private readonly AsyncLazy<MyResource> resource;
public MainPage()
{
resource = new AsyncLazy<MyResource>(async () =>
{
var a = await step0();
var b = await step1();
return new MyResource(a, b); // or whatever
});
resource.Start(); // start step0
}
public async Task MethodThatNeedsResource()
{
var r = await resource; // ensure step1 is complete before continuing
}
It's also possible to do this with an async void
method or ContinueWith
, but you'll have to carefully consider error handling with those approaches.
- The
AsyncLazy
approach will capture errors and raise them whenever await resource
is executed.
- The
async void
approach will throw errors immediately to the SynchronizationContext
.
- The naive
ContinueWith
approach will silently ignore all errors.
Whichever approach you take, I recommend having some notification in the UI that the initialization is in progress. (And as a side note, I think all of this should go into a ViewModel or Model class rather than MainPage
).
Wait
does cause a deadlock, as I explain in detail on my blog. – Ehrenberg