Почему неправильный порядок навигации от SplashScreen к MainPage - PullRequest
1 голос
/ 30 октября 2019

Я пытаюсь понять пример приложения от Microsoft. Теперь я не могу повторить следующую часть. В приложении есть классы , приложение и ExtendedSplach . Я хочу повторить загрузку на ExtendedSplash. В моем случае это простой переход с заставки на главную страницу после некоторой задержки.

Введение

Пример, который нужно сделать следующим образом.

Если приложение работает с точками останова на линии .Content = extendedSplash и .Content = rootFrame, тогда первым будет extendedSplash. Но строка .Content = extendedSplash следует после .Content = rootFrame. Конструктор ExtendedSplash вызывает LoadDataAsync, который устанавливает .Content = rootFram первым.

Однако метод LoadDataAsync содержит await call

await Startup.ConfigureAsync();

Я думаю, что таким образом первый будетextendedSplash. И мы увидим страницу загрузки.

класс приложения

...
bool loadState = (e.PreviousExecutionState == ApplicationExecutionState.Terminated);
ExtendedSplash extendedSplash = new ExtendedSplash(e, loadState);
Window.Current.Content = extendedSplash;
Window.Current.Activate();

класс ExtendedSplash

public ExtendedSplash(IActivatedEventArgs e, bool loadState)
{
    ...
    LoadDataAsync(this.activatedEventArgs);
}

private async void LoadDataAsync(IActivatedEventArgs e)
{
    ...
    rootFrame.Navigate(typeof(LoginView), shellArgs);
    Window.Current.Content = rootFrame;
    Window.Current.Activate();
}

Проблема

Я пыталсяповторить то же самое. Я хочу посмотреть loading и затем перейти на другую страницу. Но мой случай с контрольными точками выглядит как первый .Content = rootFrame, а второй .Content = extendedSplash. Таким образом, моя очередь представляет собой логотип приложения с задержкой 5 секунд и затем страницу с extendedSplash. Страница rootFrame проигрывает.

Буду благодарен за любую помощь.

Мой код

Я проделал то же самое с App class

bool loadState = (e.PreviousExecutionState == ApplicationExecutionState.Terminated);
ExtendedSplash extendedSplash = new ExtendedSplash(e, loadState);
Window.Current.Content = extendedSplash;
Window.Current.Activate();

И затем с помощью ExtendedSplash

public ExtendedSplash(IActivatedEventArgs e, bool loadState)
{
    this.InitializeComponent();

    Window.Current.SizeChanged += new WindowSizeChangedEventHandler(ExtendedSplash_OnResize);

    this.splashScreen = e.SplashScreen;
    this.activatedEventArgs = e;

    OnResize();
    rootFrame = new Frame();
    LoadDataAsync(activatedEventArgs);
}

private async void LoadDataAsync(IActivatedEventArgs e)
{
    await Test();

    rootFrame.Navigate(typeof(MainPage));
    Window.Current.Content = rootFrame;
    Window.Current.Activate();
}

private async Task Test()
{
    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();
    while (stopwatch.ElapsedMilliseconds < 5000) ;
}

1 Ответ

3 голосов
/ 30 октября 2019

Проблема с вашим кодом на самом деле в методе Test(). Вы отметили async, но это не делает метод асинхронным. Вместо этого ваш код будет фактически заблокирован на пять секунд в цикле while.

Попробуйте следующую версию:

private async Task Test()
{
    await Task.Delay(5000);
}

Эта форма кода вФакт асинхронный, так что в результате поток пользовательского интерфейса может свободно отображать заставку.

В общем - асинхронные методы выполняются в потоке, который вызывает их, пока они не достигают «фактического»асинхронный код - например, связанный с вводом / выводом асинхронный метод или когда вы запускаете свой код с await Task.Run(()=>{...}.

...