How can I call this async method in my Xamarin Forms when my app starts?

11,908

Solution 1

As far as the docs say, you have the Application.OnStart event which you can override:

Application developers override this method to perform actions when the application starts.

You can execute your async method there where it can actually be awaited:

public override async void OnStart()
{
    await LoadStorageDataAsync();
}

Solution 2

Take a step back, and think about how the UI works. When your app is initially shown, the framework constructs your ViewModel and View, and then it shows something immediately (as soon as possible). That's an inappropriate place for network activity.

Instead, what you should do is start the asynchronous operation and then (synchronously) load and show a "loading" page. When the asynchronous operation completes, then you can transition to your other pages (or to an "error" page if, say, the user does not have network access).

I'm not sure if Xamarin Forms is capable of data-binding to a page object, but if it is, then my NotifyTaskCompletion type may be helpful.

Solution 3

Constructors can't be async, but event handlers can be. If you can you should move that logic to the OnStart event handler (or a more appropriate one):

public override async void OnStart (EventArgs e)
{
    // stuff
    await LoadStorageDataAsync();
    // stuff
}

If you can't, you don't have a better choice than simply blocking synchronously on that task to get the result. You should be aware though that this can lead to deadlocks.

Share:
11,908
Pure.Krome
Author by

Pure.Krome

Just another djork trying to ply his art in this mad mad world. Tech stack I prefer to use: Laguage: C# / .NET Core / ASP.NET Core Editors: Visual Studio / VS Code Persistence: RavenDB, SqlServer (MSSql or Postgres) Source control: Github Containers: Docker & trying to learn K&'s Cloud Platform: Azure Caching/CDN: Cloudflare Finally: A Tauntaun sleeping bag is what i've always wanted spaces > tabs

Updated on July 22, 2022

Comments

  • Pure.Krome
    Pure.Krome almost 2 years

    When my app is first starting, I need to load up some previously saved data. If it exists -> then goto the TabbedPage page. Otherwise, a Login page.

    I'm not sure how I can call my async method in the app's ctor or even in another method? How can I do this?

    Here's my code..

    namespace Foo
    {
        public class App : Application
        {
            public App()
            {
                Page page;
    
                LoadStorageDataAsync(); // TODO: HALP!
    
                if (Account != null)
                {
                    // Lets show the dashboard.
                    page = new DashboardPage();
                }
                else
                {
                    // We need to login to figure out who we are.
                    page = CreateAuthenticationPage();
                }
    
                MainPage = page;
            }
    
      ... snip ...
    }
    

    So why is LoadStorageDataAsync async? Because it's using the library PCLStorage and that is all async.

  • Pure.Krome
    Pure.Krome over 8 years
    If you noticed, I'm inheriting from Application. There is no async void OnStart(...) override?
  • Pure.Krome
    Pure.Krome over 8 years
    Ahh -> it's public override async void OnStart()
  • i3arnon
    i3arnon over 8 years
    @Pure.Krome I try not to include modifiers as they aren't really related to most answers.
  • Pure.Krome
    Pure.Krome over 8 years
    modifiers? (sorry, I don't understand)
  • i3arnon
    i3arnon over 8 years
    @Pure.Krome public/private/protected, etc.
  • MoralCode
    MoralCode about 6 years
    Thank you! This was really helpful for me. I think it may be nice to add that these event handler methods don't START off being defined as async but you can change the signature and use them to start an async/await chain.