29

I have an application that has been getting strange errors when canceling out of a dialog box. The application can't continue if the box is cancelled out of, so it exits, but it is not working for some reason, and thus it keeps running and crashes.

I debugged this problem, and somehow the application runs right past the Application.Exit call. I'm running in Debug mode, and this is relevant because of a small amount of code that depends on the RELEASE variable being defined. Here is my app exit code. I have traced the code and it entered the ExitApp method, and keeps on going, returning control to the caller and eventually crashing.

This is an application which provides reports over a remote desktop connection, so that's why the exit code is a bit weird. Its trying to terminate the remote session, but only when running under release because I don't want to shut down my dev machine for every test run.

    private void ExitApp()
    {
        HardTerminalExit();
        Application.Exit();
    }

    // When in Debug mode running on a development computer, this will not run to avoid shutting down the dev computer
    // When in release mode the Remote Connection or other computer this is run on will be shut down.
    [Conditional("RELEASE")]
    private void HardTerminalExit()
    {
        WTSLogoffSession(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, false);
    }

I've run a debugger right past the Application.Exit line and nothing happens, then control returns to the caller after I step past that line.

What's going on? This is a Windows Forms application.

GEOCHET
  • 21,119
  • 15
  • 74
  • 98
Tony Peterson
  • 20,522
  • 15
  • 48
  • 66
  • For me - i had performed a different form.Show() call - closed that window and the application.exit() failed, I changed it to a form.ShowDialog() call and all was better – Michael Shelnutt Feb 24 '17 at 18:42

10 Answers10

48

This is an article which expands on the same train of thought you are going through: http://www.dev102.com/2008/06/24/how-do-you-exit-your-net-application/

Basically:

  • Environment.Exit - From MSDN: Terminates this process and gives the underlying operating system the specified exit code. This is the code to call when you are using console application.

  • Application.Exit - From MSDN: Informs all message pumps that they must terminate, and then closes all application windows after the messages have been processed. This is the code to use if you are have called Application.Run (WinForms applications), this method stops all running message loops on all threads and closes all windows of the application. There are some more issues about this method, read about it in the MSDN page.

Another discussion of this: Link

This article points out a good tip:

You can determine if System.Windows.Forms.Application.Run has been called by checking the System.Windows.Forms.Application.MessageLoop property. If true, then Run has been called and you can assume that a WinForms application is executing as follows.

if (System.Windows.Forms.Application.MessageLoop)
{
  // Use this since we are a WinForms app
  System.Windows.Forms.Application.Exit();
}
else
{
  // Use this since we are a console app
  System.Environment.Exit(1);
}
Glorfindel
  • 21,988
  • 13
  • 81
  • 109
GEOCHET
  • 21,119
  • 15
  • 74
  • 98
  • 4
    I added an additional return after the call to the exit method. That fixed the problem. – Tony Peterson Feb 17 '09 at 13:04
  • 1
    @TonyPeterson The reason this is required is that the Exit call puts an Exit message on the queue but continues to execute until the app processes the exit request, thus you need to return to end execution at that point. Wow just realised how old this is, sorry – Basic Jul 27 '13 at 21:47
  • 1
    Hi @TonyPeterson, could you please post the code of the "additional return" you added? Thanks a lot in advance. –  Oct 14 '16 at 00:07
  • I changed my code from just showing a form to using it through Application.Run ReportDisplay rd = new ReportDisplay(u, cd.reports, u.root,emails); Application.Run(rd); – Tony Peterson Jan 23 '18 at 18:53
  • How about Console or `no forms` message loop started with `Application.Run()`? I cannot kill the beast even implement own ApplicationContext with method `() => ThreadExit()`... – Sebastian Xawery Wiśniowiecki Apr 19 '20 at 21:18
7

Having had this problem recently (that Application.Exit was failing to correctly terminate message pumps for win-forms with Application.Run(new Form())), I discovered that if you are spawning new threads or starting background workers within the constructor, this will prevent Application.Exit from running.

Move all 'RunWorkerAsync' calls from the constructor to a form Load method:

public Form()
{
  this.Worker.RunWorkerAsync();
}

Move to:

public void Form_Load(object sender, EventArgs e)
{
  this.Worker.RunWorkerAsync();
}
StigM
  • 711
  • 6
  • 12
6

Try Environment.Exit(exitCode).

Nick Gunn
  • 724
  • 5
  • 10
3

I have went though this situation in many cases I use Thread.CurrentThread.Abort()

and the process is closed. It seems that Application.Exit isn't hooking up properly with current thread.

2

Also ensure any threads running in your application have the IsBackground property set to true. Non-background threads will easily block the application from exiting.

Andrew
  • 203
  • 3
  • 6
2

Make sure you have no Console.ReadLine(); in your app and Environment.Exit(1); will work and close your app.

Mark Bad
  • 53
  • 7
1

I created the following that will exit the app anywhere. You don't have to worry if the Form is running or not, the test determines that and calls appropriate Exit.

    public void exit(int exitCode)
    {
        if (System.Windows.Forms.Application.MessageLoop)
        {
            // Use this since we are a WinForms app
            System.Windows.Forms.Application.Exit()
        }
        else
        {
            // Use this since we are a console app
            System.Environment.Exit(exitCode);
        }
    } //* end exit()
spinlock
  • 17
  • 3
0

Try this :

in Program.cs file :

after Application.Run(new form());

add Application.Exit();

Ali Gh
  • 680
  • 7
  • 9
0

Is this application run (in the Main method) using Application.Run()? Otherwise, Application.Exit() won't work.

If you wrote your own Main method and you want to stop the application, you can only stop by returning from the Main method (or killing the process).

configurator
  • 40,828
  • 14
  • 81
  • 115
0
    private void frmLogin_FormClosing(object sender, FormClosingEventArgs e)
    {

        if (e.CloseReason == CloseReason.UserClosing)
        {
            DialogResult result = MessageBox.Show("Do you really want to exit?", "Dialog Title", MessageBoxButtons.YesNo);
            if (result == DialogResult.Yes)
            {
                Environment.Exit(0);
            }
            else
            {
                e.Cancel = true;
            }
        }
        else
        {
            e.Cancel = true;
        }


    }
  • 1
    Welcome Jordan, Can you please add context to how your code helps answer the question? – Lockszmith Oct 08 '21 at 19:38
  • While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. You can find more information on how to write good answers in the help center: https://stackoverflow.com/help/how-to-answer . Good luck – nima Oct 08 '21 at 21:38