1

we have an application that needs to save settings when shutting down, including when windows shuts down. We are successfully receiving the Application.Exit event in this case, but then, depending on timing the application is simply terminated. It is not like we are doing a lot more than saving two small XML files with settings. Sometimes they get saved, sometimes not, again all depending on timing.

Is there some maximum amount of time allowed for the application to clean up after receiving a signal that windows is shutting down?

The following work-around "works" but I do not understand why:

// In our main application class derived from Application:
protected override void OnSessionEnding(SessionEndingCancelEventArgs e)
{
    e.Cancel = true;
    this.Shutdown();
    base.OnSessionEnding(e);
}

This seems to work fine, and allows the application to exit in the same way as it would normally do (it is a minimize-to-tray type of app that uses ShutdownMode.OnExplicitShutdown and when quitting from the tray icon we do call Application.Shutdown explicitly).

So why does windows not allow time for the application to handle the Exit event? What causes it to force kill the application with seemingly no wait time? Is it because we have no open window left (we hide our main window when it gets minimized to the tray but do not close it)?

What about the work-around? Is it bad practice, or okish?

thehan83
  • 163
  • 1
  • 8
  • Seems similar to https://stackoverflow.com/questions/8137070/force-application-close-on-system-shutdown . Check if the answers over there can help you. – Markus Deibel Sep 30 '19 at 11:04
  • As noted in the first marked duplicate, when you get notification that the application is being closed, it may be too late to save the settings. You can do it earlier, when you get notification that the session is ending. That said, IMHO you should safe settings earlier than that, i.e. when they actually change. This addresses all of these scenarios, along with situations where the program is forcefully terminated or crashes. See second marked duplicate. – Peter Duniho Oct 02 '19 at 02:16
  • Once you get the OnSessionEnding call, you need to clean up everything inside this method, "without" closing all the windows of the app. Your app might get terminated at any point after that. Calling shutdown is not a good idea since it closes all the windows and because of that, windows won't wait for your app anymore. it doesn't matter if you set e.Cancel or use ShutdownMode.OnExplicitShutdown. – Mehrzad Chehraz Oct 02 '19 at 02:27

1 Answers1

3

When you're closing your computer down you may have noticed a window pops up telling you application xyz is still running, do you want to close it.

Thеre are mechanisms built into windows which are intended to handle the scenario where an application is running and a user will likely want to save work before shutting down.

Application session ending is intended to be used for this sort of thing. The documentation elaborates somewhat: https://learn.microsoft.com/en-us/dotnet/api/system.windows.application.sessionending?redirectedfrom=MSDN&view=netframework-4.8

By default, an application shuts down when the Windows session ends, which occurs when a user logs off or shuts down. When this happens, Windows asks each open application to shut down. However, it is possible that an application may not be ready to shut down when this occurs. For example, an application may have data that is in an inconsistent state, or in the middle of a long-running operation. In these situations, it may be desirable to prevent the session from ending, and may be more desirable to allow users the option to decide whether or not to let the session to end.

So session ending is designed for your scenario.

Application exit is not.

That event will fire quite late on in the process of shutting an app down and does not interrupt that process. It's for that reason it's a bad place to put any code you are relying on to save settings.

pstrjds
  • 16,840
  • 6
  • 52
  • 61
Andy
  • 11,864
  • 2
  • 17
  • 20