【问题标题】:How can I call this async method in my Xamarin Forms when my app starts?当我的应用程序启动时,如何在我的 Xamarin Forms 中调用此异步方法?
【发布时间】:2019-10-11 05:27:16
【问题描述】:

当我的应用第一次启动时,我需要加载一些以前保存的数据。如果它存在 -> 然后转到 TabbedPage 页面。否则,一个登录页面。

我不确定如何在应用程序的 ctor 甚至其他方法中调用我的异步方法?我该怎么做?

这是我的代码..

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 ...
}

那么为什么LoadStorageDataAsync 是异步的?因为它是using the library PCLStorage,而且都是异步的。

【问题讨论】:

    标签: c# asynchronous async-await xamarin.forms


    【解决方案1】:

    As far as the docs say,您有可以覆盖的Application.OnStart 事件:

    应用程序开发人员重写此方法以在以下情况下执行操作 应用程序启动。

    你可以在那里执行你的 async 方法,在那里实际上可以等待它:

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

    【讨论】:

      【解决方案2】:

      退后一步,想想用户界面的工作原理。当您的应用最初显示时,框架会构建您的 ViewModel 和 View,然后它会立即(尽快)显示一些东西。那是不适合进行网络活动的地方。

      相反,您应该启动异步操作,然后(同步)加载并显示“加载”页面。异步操作完成后,您可以转换到其他页面(或者如果用户没有网络访问权限,则转换到“错误”页面)。

      我不确定 Xamarin Forms 是否能够将数据绑定到页面对象,但如果是,那么我的 NotifyTaskCompletion type 可能会有所帮助。

      【讨论】:

        【解决方案3】:

        构造函数不能是async,但事件处理程序可以。如果可以的话,您应该将该逻辑移至OnStart 事件处理程序(或更合适的处理程序):

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

        如果你不能,除了简单地在该任务上同步阻塞以获得结果之外,你没有更好的选择。您应该注意,这可能会导致死锁。

        【讨论】:

        • 如果你注意到了,我继承自 Application。没有async void OnStart(...)覆盖?
        • 啊 -> 这是public override async void OnStart()
        • @Pure.Krome 我尽量不包含修饰符,因为它们与大多数答案并不真正相关。
        • 修饰符? (对不起,我不明白)
        • @Pure.Krome public/private/protected 等
        【解决方案4】:

        在构造函数中使用异步方法被认为是糟糕的代码。您不应该在类构造函数中使用异步方法。

        您可以尝试更改它以避免死锁:

        Func<Task> task = async () => { 
            await YourCustomMethodAsync().ConfigureAwait(false); 
        };
        task().Wait();
        

        ...但我不会推荐它。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-06-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-12-10
          • 2019-11-12
          • 1970-01-01
          相关资源
          最近更新 更多