Когда я закрываю AppWindow, почему я не могу открыть новый AppWindow - PullRequest
2 голосов
/ 13 июля 2020

Я использую AppWindow в своем приложении UWP. В большинстве случаев все идет хорошо, но иногда, когда я закрываю окно приложения, наблюдается странное поведение.

Иногда кажется, что окно приложения не закрывается должным образом. Я заметил, что окно приложения кажется закрытым (содержимое окна приложения исчезло), но заголовок окна приложения переместился в строку заголовка главного окна. После этого, если я попытаюсь открыть новое окно приложения с помощью appWindow.TryShowAsyn c (), произойдет сбой с исключением «Элемент не найден. (Исключение из HRESULT: 0x80070490)»

Я делаю windows очистка приложения, как показано в документации Microsoft, и в большинстве случаев я могу закрыть окно приложения и открыть новое окно несколько раз.

Есть идеи, почему иногда это не работает?

Dan

PS В документации есть примечание от Microsoft от 19.07.2019, в котором говорится: «AppWindow в настоящее время находится в предварительной версии. Это означает, что вы можете отправлять приложения которые используют AppWindow в Магазин, но известно, что некоторые компоненты платформы и фреймворка не работают с AppWindow ». Сейчас, когда мы находимся в середине 2020 года, AppWindow все еще находится в режиме предварительного просмотра?

Обновление 2020-07-15

As Faywang - MSFT предложил, я создал небольшое тестовое приложение, чтобы попытаться воспроизвести проблему. Пока я не могу воспроизвести проблему с тестовым приложением, но вот обновление с дополнительными данными.

Я много тестировал и обнаружил, что проблема возникает еще реже с выпускной сборкой моего приложения, а не с отладочной сборкой. Итак, я почти готов сдаться и списать странное поведение на альфа-частицы, приходящие из космоса и почти меняющие единицы на ноль. :)

Я обнаружил, что могу заставить проблему возникать в моем приложении без выполнения пользователем каких-либо значительных операций. То есть, если я запускаю приложение, открываю окно приложения, а затем закрываю окно приложения, проблема может возникнуть (примерно после 10-20 попыток). Когда я проделываю ту же последовательность с моим тестовым приложением, я еще не заметил, чтобы проблема возникла.

Итак, у меня все еще нет ответа, но у меня есть две новые теории. Последняя теория состоит в том, что, возможно, моя главная страница и связанный с ней Xaml не инициализируются должным образом (и именно поэтому в окне приложения позже возникают проблемы). Я говорю это, потому что в моем реальном приложении я вижу эти сообщения до , появляется окно приложения

onecoreuap \ windows \ wgi \ winrt \ display \ displaycommon. cpp (411 ) \ Windows .Graphics.dll! 00007FFCE38B04B0: (вызывающий: 00007FFCE38B01F5) ReturnHr (1) tid (6358) 80070490 Элемент не найден.

onecoreuap \ windows \ wgi \ winrt \ display \ displaycommon. cpp (411) \ Windows .Graphics.dll! 00007FFCE38B04B0: (вызывающий: 00007FFCE38B01F5) ReturnHr (2) tid (6358) 80070490 Элемент не найден.

onecoreuap \ windows \ wgi \ winrt \ display \ displaycommon . cpp (411) \ Windows .Graphics.dll! 00007FFCE38B04B0: (вызывающий: 00007FFCE38B017A) ReturnHr (3) tid (6358) 80070490 Элемент не найден.

onecore \ com \ combase \ objact \ dllcache.cxx (4713) \ combase.dll! 00007FFCEB90964E: (вызывающий: 00007FFCEB811D1D) ReturnHr (1) tid (6358) 80040111 ClassFactory не может предоставить запрошенный класс

Первое сообщение появляется, когда я показываю изображение на главной странице. Следующие три появляются, когда я использую всплывающее меню для вызова окна приложения. Я не вижу этих сообщений, когда вызываю окно приложения в своем тестовом приложении. Я игнорировал эти сообщения, потому что главная страница, кажется, работает нормально, и всплывающее меню работает нормально, но, возможно, был нанесен некоторый ущерб. Когда я ищу эти сообщения в Интернете, они кажутся довольно неопределенными c и связаны с множеством других сбоев, не имеющих ничего общего с приложением Windows.

Есть ли у кого-нибудь понимание этих сообщений?

Другая теория заключается в том, что это поведение главного окна / окна приложения не имеет ничего общего с моим кодом, но представляет собой своего рода проблему с Visual Studio 2019, захватывающей разные Windows dll (например, Windows . Graphics.dll) для сборки с моим кодом. Настоящее приложение создавалось и перестраивалось за последние несколько месяцев и с разными версиями VS2019, но тестовое приложение было создано только вчера. Я только что обновился до новой версии VS2019, 16.6.4. Я думал, что если я удалю папки bin и obj, а затем перестрою свое приложение с последней версией VS, не может быть никакого остаточного эффекта от создания с более ранние версии.

Это правильное мышление?

Еще одна вещь. Я обнаружил, что когда я закрываю окно приложения и при закрытии возникает странное поведение, запускается событие ApplicationView.Consolidated, и оба IsAppInitiated и IsUserInitiated ложны. Это событие «происходит, когда окно удаляется из списка недавно использованных приложений или если пользователь закрывает его».

Означает ли это, что Windows думает, что пользователь пытается закрыть главное окно, когда пользователь фактически пытается закрыть окно приложения?

Dan

Обновление # 2 2020-07-15

As Иван Вергес подсказал, выкладываю какой-то код. Я отправляю это как ответ, выдумывая желаемое за действительное. Может, кто-то увидит, что здесь не так, и тогда я отредактирую это в ответ. :)

Вы увидите, что мой код в основном скопирован из примера Microsoft о « Показать несколько представлений с помощью AppWindow

Иван также поинтересовался, есть ли у меня службы, или фоновой задачи, или других объектов данных с длительным сроком службы. Ответ на этот вопрос - нет для служб или фоновых задач. Что касается других объектов данных с длительным сроком службы, я не храню их в своем классе EditPage (который используется для окна приложения). Я храню объекты с длительным сроком службы в моем классе MainPage (который используется для главного окна) и просто отображаю их в элементах управления на странице редактирования. Вот мой код для создания окна приложения (я называю его окном редактирования в моем приложении). И код, который вызывается при закрытии окна (пользователем)

   // helper fcn launches the Edit window
    private async Task ShowEditAppWindow()
    {
        if (AppWindows.Count > 0)
        {
            MainFlyout.Hide();
            return;
        }

    // Create a new window.
    AppWindow appWindow = await AppWindow.TryCreateAsync();

    // Create a Frame and navigate the Frame to a XAML-style Page object
    Frame appWindowContentFrame = new Frame();
    appWindowContentFrame.Navigate(typeof(EditPage));

    // Attach the XAML content to the window
    ElementCompositionPreview.SetAppWindowContent(appWindow, appWindowContentFrame);

    // Add the new page to the Dictionary using the UIContext as the Key.
    AppWindows.Add(appWindowContentFrame.UIContext, appWindow);
    appWindow.Title = "Edit Window ";

    // When the window is closed, be sure to release
    // XAML resources and the reference to the window. 
    appWindow.Closed += (ss, ee) => AppWindow_Closed(ss, ee, appWindowContentFrame);

    // try to show the Edit window
    InEditState = false;
    bool successShowing = false;

    try
    {
        successShowing = await appWindow.TryShowAsync();
    }
    catch (Exception ex)
    {
        successShowing = false;
        Debug.WriteLine("Failure showing Edit window. " + ex.Message);
    }
              
    if (successShowing)
    {
        InEditState = true;
    }
    else
    {
        // clean up attempted window
        MainPage.AppWindows.Remove(appWindowContentFrame.UIContext);
        appWindowContentFrame.Content = null;
        appWindow = null;
        InEditState = false;            }

}

   private void AppWindow_Closed(AppWindow sender, AppWindowClosedEventArgs args, 
        Frame appWindowContentFrame, AppWindow appWindow)
    {
        Debug.WriteLine("in AppWindow_Closed handler");
        MainPage.AppWindows.Remove(appWindowContentFrame.UIContext);
        appWindowContentFrame.Content = null;
        appWindow = null;
        InEditState = false;

    // set a variable to indicate the appWindow just closed
    EditWindowJustClosed = true;

    // start timer to clear that indication
    EditWindowJustClosedTimer.Start();

    // always get show going after edit window closes
    SlideTimer_Tick(null, null);        // simulate timeout of the Slide timer
}

1 Ответ

0 голосов
/ 17 июля 2020

У меня нет идеального ответа на этот вопрос, но теперь у меня есть довольно хороший ответ. Я нашел кое-что и узнал кое-что, что снизило возникновение проблемы (которая и так была довольно низкой).

Меня беспокоило появление сообщений об ошибках в моем приложении, которые я сделал не вижу в простом тестовом приложении. Я нашел этому объяснение. Это была настройка проекта в Visual Studio. То есть параметр, используемый для тестового приложения, включал вкладку «Отладка» | Тип отладчика = только управляемый. Настройки, которые я использовал для своего реального приложения, включали вкладку Debug | Тип отладчика = смешанный (управляемый и собственный). Я смутно помню, как менял это однажды, вероятно, через месяц go, когда я искал что-то другое. По-видимому, я забыл вернуть его обратно.

Весь мой код - это управляемый код, поэтому я был рад увидеть, что как только я использовал настройку Managed Only, сообщения о Windows dll исчезли из окна вывода и сделали это как тестовое приложение. Однако это объяснение устранило две теории, которые я предложил для объяснения проблемы с окном приложения.

Стефан высказал новую теорию. Он сказал, что существует практическое правило, согласно которому код в обработчике OnClosed минимален. Я слышал о минимальном количестве кода в обработчике, который вызывается во время процесса закрытия, например обработчика OnClosing, но, видимо, вы также хотите сократить время выполнения обработчика OnClode. Спасибо, Стефан!

Итак, я уменьшил объем кода, выполняемого в обработчике OnClosed, и это помогло. Я все еще вижу, что проблема возникает, но сейчас ее очень трудно воспроизвести.

На данный момент это мое решение.

Всем спасибо!

Дэн

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...