When I close an AppWindow, why can't I open a new AppWindow

2

I am using an AppWindow in my UWP app. Most of the time things are good, but occasionally when I close the app window there is some strange behavior.

Occasionally, the app window does not seem to close properly. What I observe is that app window seems to close (the content of the app window is gone), but the title of the app window has moved to the main window title bar. After this happens, if I try to open a new app window, using appWindow.TryShowAsync(), it fails with the exception "Element not found. (Exception from HRESULT: 0x80070490)"

I do the app windows cleanup as shown in the Microsoft documentation and, most of the time, I can close an app window and open a new app window multiple times.

Any idea why it sometimes does not work?

PS In the documentation there is a note from Microsoft dated 07/19/2019 that says, "AppWindow is currently in preview. This means you can submit apps that use AppWindow to the Store, but some platform and framework components are known to not work with AppWindow." Now that we’re in the middle of 2020, is AppWindow still in “preview?”

Update 2020-07-15

As Faywang – MSFT suggested, I created a small test app to try to reproduce the problem. So far, I can’t reproduce the problem with the test app, but here’s an update with some more data.

I’ve been doing a lot of testing and I did discover that the problem occurs even less frequently with a release build of my app, versus a debug build. So, I’m almost ready to give up and chalk up the strange behavior to alpha particles coming from space in and flipping 1’s to 0’s, almost. :)

I discover that I can get the problem to occur in my app without the user doing any significant operations. That is, if I launch the app, bring up the app window, then close the app window, the problem can occur (after about 10 – 20 attempts). When I do that same sequence with my test app, I have not seen the problem occur, yet.

So, I still don’t have an answer, but I do have two new theories. The latest theory is that maybe my main page, and its associated Xaml, does not get initialized properly (and that’s why the app window has problems later). I say that because in my real app, I see these messages before the app window appears

onecoreuap\windows\wgi\winrt\display\displaycommon.cpp(411)\Windows.Graphics.dll!00007FFCE38B04B0: (caller: 00007FFCE38B01F5) ReturnHr(1) tid(6358) 80070490 Element not found.

onecoreuap\windows\wgi\winrt\display\displaycommon.cpp(411)\Windows.Graphics.dll!00007FFCE38B04B0: (caller: 00007FFCE38B01F5) ReturnHr(2) tid(6358) 80070490 Element not found.

onecoreuap\windows\wgi\winrt\display\displaycommon.cpp(411)\Windows.Graphics.dll!00007FFCE38B04B0: (caller: 00007FFCE38B017A) ReturnHr(3) tid(6358) 80070490 Element not found.

onecore\com\combase\objact\dllcache.cxx(4713)\combase.dll!00007FFCEB90964E: (caller: 00007FFCEB811D1D) ReturnHr(1) tid(6358) 80040111 ClassFactory cannot supply requested class

The first message appears when I show an image on the main page. The next three appear when I use a flyout menu to invoke the app window. I don’t see those messages when I invoke the app window in my test app. I had been ignoring those messages because the main page seems to work fine, and the flyout menu works fine, but maybe some damage has been done. When I search for theses messages on the web, they seem to be pretty non-specific and related to a lot of other failures that have nothing to do with App Windows.

Does anyone have an insight from those messages?

Another theory is that this main window / app window behavior has nothing to do with my code but is some sort of problem with Visual Studio 2019 grabbing different Windows dlls (like Windows.Graphics.dll) to build with my code. The real app has been built and rebuilt over the past few months, and with different versions of VS2019, but the test app was just built yesterday. I just updated to new version of VS2019, 16.6.4 I had been thinking that if I delete the bin and obj folders and then rebuild my app with the latest version of VS, there can’t be any residual effect of having been built with earlier versions.

Is that correct thinking?

One more thing. I discovered that when I close the app window and the odd behavior occurs on closing, the event ApplicationView.Consolidated has fired, and both IsAppInitiated and IsUserInitiated are false. That event “occurs when the window is removed from the list of recently used apps, or if the user executes a close gesture on it.”

Does that mean that Windows thinks the user is trying to close the main window when the user is actually trying to close the app window?

Update#2 2020-07-15

As Ivan Verges suggested, I’m posting some code. I’m posting this as an answer with a little wishful thinking. Maybe someone will see what’s wrong here and then I’ll edit it into an answer. :)

You’ll see that my code is mostly copied from the Microsoft example about “Show multiple views with AppWindow.”

Ivan also wondered if I had a service, or a background task, or other long lifetime data objects. The answer to that is no for services or background tasks. As far as other long lifetime data objects, I don’t keep those in my EditPage class (that’s used for the app window). I keep long lifetime objects in my in the MainPage class (that’s used for the main window) and just display those in the controls on the edit page. Here’s my code to create the app window (I call it the Edit window in my app). And the code that gets called when the window gets closed (by the user)

   // 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
}
c#
uwp
window
uwp-appwindow
asked on Stack Overflow Jul 13, 2020 by Dan Scavezze • edited Apr 25, 2021 by Mikael Dúi Bolinder

1 Answer

0

I don’t have a perfect answer to this question, but I now have an answer that is pretty good. I found some things, and learned some things, that have reduced the occurrence of the problem (which was already pretty low).

One thing that bothered me was the occurrence of the error messages in my app that I did not see in the simple test app. I did find an explanation for that. It was a project setting in Visual Studio. That is, the setting used for the test app included Debug Tab | Debugger type = Managed Only. The settings I was using for my real app included Debug Tab | Debugger type = Mixed (Managed and Native). I vaguely remember changing that at one point, probably a month ago, when I was search for something else. Apparently, I forgot to change it back.

All of my code is managed code so I was glad to see that once I used the Managed Only setting, messages about Windows dlls disappeared from the Output Window and made it just like the test app. However, that explanation eliminated two of the theories I had proposed to explain the app window problem.

Stefan had a new theory. He said that there was a rule of thumb to keep the code in OnClosed handler minimal. I have heard about keeping code minimal in a handler that gets called during the close process, like an OnClosing handler, but apparently you want to keep the execution time of the OnClode handler short too. Thanks Stephan!

So, I reduced the amount of code that gets executed in the OnClosed handler and that helped. I can still see the problem occur, but its very difficult to reproduce now.

For now, this is my solution.

Thanks all!

Dan

answered on Stack Overflow Jul 17, 2020 by Dan Scavezze

User contributions licensed under CC BY-SA 3.0