Xamarin дождитесь завершения задачи, прежде чем продолжить - PullRequest
0 голосов
/ 23 января 2019

По сути, я пытаюсь загрузить другую страницу, однако мне нужно что-то из другого метода, чтобы завершить инициализацию, при инициализации 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}");
}

Когда я определяю страницу сразу после попытки, она вернет мне страницу после того, как все будет инициализировано, однако я получаю нулевые ссылочные объекты в нескольких местах, а иногда код работает совершенно нормальноза несколько попыток я могу поверить, что это нити: если я тороплюсь с этим, он рушится, если я беру его медленнее, обычно все в порядке.

Что я хотел бы сделать, так это остальноекод ожидает, пока Пейдж не вернет что-то к нему.Это возможно?Спасибо!

В методе 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--;
            } 

1 Ответ

0 голосов
/ 24 января 2019

при инициализации ViewModel вызывает сервер, поэтому я ждал этого, так как мне нужно, чтобы остальная часть приложения подождала, прежде чем продолжить, предпочтительно асинхронно

Я настоятельно рекомендую, чтобы ViewModels всегда инициализировались синхронно. Единственный разумный способ сделать это - синхронно загрузить его в состояние «загрузки» (и запустить вызов на сервер). Позже, когда у вас есть данные для отображения, обновит виртуальную машину в «загруженном» состоянии. Это даст вашим пользователям гораздо лучший опыт, показывая им сообщение «Загрузка ...» или счетчик, а не заставляя их ждать завершения удаленного вызова.

Дополнительная информация в моей статье об асинхронной привязке данных MVVM и небольшая вспомогательная библиотека .

...