Bryce Wagner
Bryce Wagner

Reputation: 2650

Show dialog after Application.Exit()

Under certain circumstances, I wish to display an error message to the user if the application didn't shut down properly, but MessageBox.Show() doesn't actually do anything after calling Application.Exit(). Is there a way to convince it to show a dialog after Application.Exit()?

Upvotes: 1

Views: 2699

Answers (5)

Jason Lim
Jason Lim

Reputation: 171

So far, I haven't been able to find much info on this problem. However, I did find a seemingly relevant discussion here. After a bit of research, I managed to find something of a solution, but it only allows you to use message boxes in your Main function after the initial Application.Run call has returned.

Note: All the following investigation has been done under .Net Framework 4.5.

From the forum discussion, it looks like calling Application.Exit in a window thread after calling Application.Run(Form) causes the Application system to move into a shutdown state. In this state, no new calls to Application.Run(Form) will work and no message boxes can be shown. On the other hand, if you call Application.Exit from a window thread after calling Application.Run(new ApplicationContext()) or just Application.Run(), this situation does not happen. It is okay to call Application.Run again and message boxes work like normal.

After a bit of experimentation, I found that if you call Application.Run() (no form) after entering the shutdown state, two things happen. The first is that the Application.Run() call immediately exits. The second is that shutdown state is cleared and regular behavior is resumed. This is great, but it presents a problem: if you have not called Application.Exit from your form, the formless Application.Run() call will block indefinitely as it waits for one to occur.

To solve this, you can use the Application.Idle event to rescue yourself from the blocked state. At first I tried:

Application.Run(new Form1()); // Calls Application.Exit()

Application.Idle += (o, e) => Application.Exit();
Application.Run();

MessageBox.Show("Close, but no banana...");

But for whatever reason, in this case the Application.Exit() call behaves similarly to if you were calling Application.Exit() while inside a Application.Run(Form) call. We run into the same situation where message boxes don't show and subsequent Application.Run calls don't work.

A bit more experimentation, and I found that the following does work:

Application.Run(new Form1()); // Calls Application.Exit()

Application.Idle += (o, e) => Task.Run(() => Application.Exit());
Application.Run();

MessageBox.Show("I'm alive!");

It's a bit ugly, and it looks purely nonsensical for anyone not in the know, but it seems to get the job done. Message boxes work as expected and it is possible to call either of the Application.Run functions again.

One last thing I should note is that it seems Application.Exit calls are queued. That is to say, you must call Application.Run() once for every time Application.Exit is called inside the form thread in order to clear the shutdown state. So if it is possible that your program may call Application.Exit multiple times, then the above solution won't work.

I haven't tested the following, but something like this should work if you're dealing with multiple Application.Exit calls:

Application.Run(new Form1()); // Calls Application.Exit() multiple times

bool done = false;
while(!done)
{
    // Application.Idle is cleared after each run
    Application.Idle += (o, e) =>
    {
        done = true;
        Task.Run(() => Application.Exit());
    };
    Application.Run();
}

MessageBox.Show("I'm alive!");

At this point, it's probably better to wrap this in some sort of helper function, but I'll leave that up to the developer's preference.

In any case, I hope this helps anyone else who runs into this problem. The Application.Run behavior seems awfully irregular, so I'm going to assume this is a bug. But if anyone else wants to take up the investigation on this, you're more than welcome.

Upvotes: 0

Daniel Rose
Daniel Rose

Reputation: 17648

Before exiting, the application fires the ApplicationExit event (WinForms) or Exit event (WPF). As part of your event handler code, you can show messsage boxes, for example. For example, in my application I show a "Do you want to save the unsaved changes?" dialog box, if applicable.

Note that it is not possible to cancel the exit in the event handler.

Upvotes: 0

shf301
shf301

Reputation: 31394

Nothing gets called after Application.Exit(). Application.Exit() does not return (unless the exit is canceled), it exits the application. After calling Application.Exit() the process is no longer running, so there is no way to get code to run after your processes has exited.

Does you code call Application.Exit()? If so change you calls to Application.Exit() to call MyApplication.Exit() where MyApplication is:

public static class MyApplicaiton {
     public static void Exit() {
          MessageBox.Show("Exiting Message");
          Application.Exit();
      }
}

Upvotes: 0

Gern Blanston
Gern Blanston

Reputation: 42660

I'm assuming this is a window's app, so in the Program.cs you could the code below ... this assumes you create a public prop or field 'ExitOk' and set as needed in the mainform.

MainForm mf = new MainForm();
Application.Run(mf);
if (mf.ExitOk)
{MessageBox.Show("Exiting OK");}
else
{MessageBox.Show("Exiting Not OK");}

One point to note is that you might need to set mf to NULL or something like that at the end also.

Any one else want to comment on any other 'clean up' that might be need?

Upvotes: 0

amit kumar
amit kumar

Reputation: 21032

You will have to use a parent process that launches the Application. When the Application returns the return value is available to the parent process. If the return value of the Application is non-zero (not a success), then show the MessageBox from the parent process.

Upvotes: 2

Related Questions