Xamarin.Forms Async Task On Startup

When you start up your Xamarin.Forms application, the constructor in your App.xaml.cs will be run, before your application is shown on screen. As you are well aware, constructors currently don’t have the ability to await async methods. They are a number of ways to solve this, depending upon your exact situation.

Not Dependent Upon Result

If you do not care about the result of your async Task, and you just want to run it, then you can do it in the constructor, and even just push it to a background thread.

Task.Run(async ()=> { await MyMethod(); });

However, it would be recommended to actually place it in the OnStart method. Add the async keyword in here. Since OnStart is just an event, and nothing is waiting for it’s return, using async void is acceptable here.

protected override async void OnStart()
{
    // Handle when your app starts
}

Required Before App Start

If you need this to run, before your app starts, and it’s not required to run on the UI Thread, you have the option to Wait your async Task.

Task.Run(async()=>{ await MyMethod(); }).Wait();

You must be careful with this approach, as if this task, calls the UI Thread at any point, it will cause a deadlock.

The other option, is to launch a loading screen. If you have control over your app, then set the MainPage to a loading screen.

MainPage = new LoadingPage();

Then run your tasks in OnStart, and when they are finished, load your actual application.

protected override async void OnStart()
{
    await MyMethod();

    MainPage = new MyActualApplicationPage();
}

Required Before App Start On UI Thread

If none of these work for you because you have to do an async task, in the constructor, on the UI Thread, then there is an option for this. The code itself is a little complex to explain, hence you can just copy the Exrin ThreadHelper.cs and place it in your project.

Exrin.Common.ThreadHelper.Init(SynchronizationContext.Current);
Exrin.Common.ThreadHelper.RunOnUIThread(async () => { await MyMethod(); });

This will run the async method, on the same thread, and will not proceed until it is complete. While requiring an async method to run on the UI Thread in the constructor is a rare occurrence, it can be required sometimes, but this is considered one of the last options you should try.

Microsoft MVP | Xamarin MVP | Xamarin Certified Developer |
Exrin MVVM Framework | Xamarin Forms Developer | Melbourne, Australia

Related Posts

5 Comments

  1. Eric Brunner

    Thanks for sharing that solutions. In app development I first learned to add a solid exception handling , especially with aaynchronous programming. Therefore I would strongly suggest to wrap a try-catch (AggregateException) around the awaited task of the second Task.Run(….).Wait(); statement and inside the lamdas, too to introduce some fail safe mechanisms. Uncaught exceptions in .ctors are terrible because a further attempt to create an instance of that class would fail.

    In general I prefer the OnStart method as you described for “real” asynchronous code.

    The Application instance could be created by introducing a factory pattern and put an awaited InitializeAync in the CreateInstance method, too.

    1. Adam Pedley

      Thanks, a good tip to concern yourself with exceptions, especially in Tasks. Using the
      .ContinueWith((t)=> {
      if (t.Exception != null)
      // Do something
      });

      Is another way to detect an unhandled exception.

    1. Adam Pedley

      Hi Eric

      Since the UI hasn’t been loaded yet, using .Wait() is acceptable, but as mentioned, you need to be careful, with deadlocks. Meaning you can’t switch back to the UI Thread, in that background thread. I do try to avoid using .Wait() or .Result, and I certainly don’t use them once the app is loaded.

      The Factory Pattern and Composing with Asynchronous Initialization are ok, but it still doesn’t block construction. When we are starting Xamarin Forms, that App constructor needs to return to finish loading the app. If we MUST complete something in the constructor before the app loads, these patterns don’t cut it. We have no async capable function of sitting there and waiting for the result. It all has to be done synchronously.

      If you can return from the constructor, then continue on with the async operation, I would just recommend putting it in OnStart, and it saves all that additional setup anyway.

      Thanks for providing another alternative. 🙂

Leave A Comment?