【问题标题】:Xamarin wait for task to be complete before continuingXamarin 等待任务完成后再继续
【发布时间】:2019-01-23 15:44:30
【问题描述】:

基本上我正在尝试加载另一个页面,但是我需要其他方法的东西来完成初始化,在初始化时 ViewModel 调用服务器,因此我一直在等待它,但是,因为我需要其余的应用程序在继续之前等待,最好是异步的。

try
{
   Page Page = await Task.Run(() => ReturnPageToLoad(item));
   if (Page != null)
   {
      PageToLoad = Page;
      Device.BeginInvokeOnMainThread(() =>
      {
          try
          {
              Detail = PageToLoad;
              _nav.SetLoadedPage(PageToLoad);
           }
           catch (Exception e)
           {
              Console.WriteLine($"Error in MainView: {e.Message}");
           }
      });
   }
} catch (Exception e)
{
   Console.WriteLine($"Error: {e.Message}");
}

我在尝试下定义页面的地方,一旦一切都初始化,这将返回一个页面给我,但是,我在多个地方得到空引用对象,有时代码在几次尝试中完全正常,什么让我相信这是线程,如果我冲进去,它会崩溃,如果我放慢它通常没关系。

我想做的是让其余的代码等到 Page 有东西返回给它。这可能吗?谢谢!

在 ReturnPageToLoadItem 方法中

            try
            {
                if (item.MenuItemType == MenuItemType.Settings)
                {
                    Page Loaded = _nav.ReturnPreLoadedPage(typeof(SettingsView));
                    await (Loaded.BindingContext as ViewModelBase).InitializeAsync(null);
                    if (_nav.returnLoadedPage() != Loaded.GetType())
                    {
                        return Loaded;
                    }
                }
                else if (item.MenuItemType == MenuItemType.MyTimetable)
                {
                    Page Loaded = _nav.ReturnPreLoadedPage(typeof(TimetableView));
                    await (Loaded.BindingContext as ViewModelBase).InitializeAsync(null);
                    if (_nav.returnLoadedPage() != Loaded.GetType())
                    {
                        return Loaded;
                    }
                }
                else if (item.MenuItemType == MenuItemType.Support)
                {
                    Page Loaded = _nav.ReturnPreLoadedPage(typeof(ChatView));
                    await (Loaded.BindingContext as ViewModelBase).InitializeAsync(null);
                    if (_nav.returnLoadedPage() != Loaded.GetType())
                    {
                        return Loaded;
                    }
                }
                else if (item.MenuItemType == MenuItemType.Applications)
                {
                    return null;
                }
                else if (item.MenuItemType == MenuItemType.MyProfile)
                {
                    Console.WriteLine("Doesn't exist yet");
                    return null;
                }
                else if (item.MenuItemType == MenuItemType.About)
                {
                    Console.WriteLine("Doesn't exist yet");
                    return null;
                }
                else if (item.MenuItemType == MenuItemType.Home)
                {
                    Page Loaded = _nav.ReturnPreLoadedPage(typeof(HomeView));
                    await (Loaded.BindingContext as ViewModelBase).InitializeAsync(null);
                    return Loaded;
                }
            }
            catch (Exception e)
            {
                await Task.Delay(50);
                Console.WriteLine($"Failed to load on attempt {retry}: {e.Message}");
                retry--;
            } 

【问题讨论】:

  • 看来问题出在ReturnPageToLoad(item) 并且您没有提供该代码。
  • 对不起!我将编辑我的 OP 以包含代码
  • @SushiHangover 添加了额外的代码!感谢您的帮助!
  • 我在多个地方得到空引用对象 什么地方? 有时代码会起作用 您会遇到哪些错误或您认为哪些行为是错误的。你能发布完整的ReturnPageToLoad 方法吗?目前尚不清楚您要修复什么行为。
  • 抱歉@JSteward 我设法修复了我的空引用错误,但是现在它在点击 Detail = PageToLoad 时对我说“Detail 必须没有父级”

标签: c# xamarin async-await task


【解决方案1】:

在初始化时 ViewModel 会调用服务器,因此我一直在等待它,因为我需要应用程序的其余部分在继续之前等待,最好是异步的

我强烈建议始终同步初始化 ViewModel。唯一合理的方法是将其同步加载到“加载”状态(并启动对服务器的调用)。稍后,当您有要显示的数据时,更新虚拟机进入“加载”状态。通过向用户显示“正在加载...”消息或微调器,而不是让他们等待远程调用完成,这将为您的用户提供更好的体验。

更多信息在我的article on async MVVM data binding 和small helper library。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-25
    • 2019-11-01
    • 2021-05-06
    • 2021-05-21
    • 1970-01-01
    相关资源
    最近更新 更多