windows-runtimeexitdispatchermessagedialog

Halt code's execution, but not the application


First off the code, which runs without error but isn't covering everything I need it to:

public async Task SaveData()
{
    // MessageDialog restartMessage;
    // ^^ This was made global and is defined in SafeToSave()

    // Check if it's safe to save
    await SafeToSave();
    if (restartMessage != null)
    {
        CoreDispatcher cD = Window.Current.CoreWindow.Dispatcher;
        await cD.RunAsync(CoreDispatcherPriority.Normal, async () =>
        {
            await restartMessage.ShowAsync();
            // This WILL invoke 'Application.Current.Exit()'
        });

        return;
        // Issue is right around here...
    }

    // Other code...

}

The basic premise is that if it is not safe to save, a message dialog will tell the user that the app needs to be restarted and then perform 'Application.Current.Exit()' when they then tap the 'Okay' button.

My problem is that I need my code to stop executing when that restart is hit. Right now 'return' only ends this method, but after that it will continue to do other things in the method that called SaveData() until my restartMessage takes effect, and that's not good.

I considered putting 'Application.Current.Exit()' above the 'return' statement, but that will shut things down before my error message can be seen. Which is also not good.

The other solution was skipping the whole CoreDispatcher thing and just running ShowAsync() by itself, except that would trigger a different known error. Basically I have a few MessageDialogs that call the SaveData() method and opening a MessageDialog when another MessageDialog is already open is, again, not good.

That's about it: I need something to stop my code form executing without killing the whole application or preventing my error message from displaying. What can I do?


Solution

  • Short version, I used this guy's solution: MessageDialog ShowAsync throws accessdenied exception on second dialog

    Since I can't control when the Dispatcher is going to occur, it's necessary to scrap it. Now I said I couldn't do that because it was preventing another bug, so I used the advice in that link to prevent that bug in a different way... so now I can ditch the Dispatcher and force my application to deal with my message dialog without it continuing along its multi-threaded path and doing things it shouldn't!

    Code for my solution is moved into the SafeToSave() method. I did what the guy in that link did and then changed this:

    CoreDispatcher cD = Window.Current.CoreWindow.Dispatcher;
    await cD.RunAsync(CoreDispatcherPriority.Normal, async () =>
    {
        await restartMessage.ShowAsync();
    });
    

    Into this:

    await restartMessage.ShowAsync();
    

    And unlike before I'm not getting an access error for calling ShowAsync() while another MessageDialog is already up, because I'm forcibly closing it first.