Winforms: Application.Exit VS Environment.Exit VS Form.Close

Winforms: Application.Exit vs Environment.Exit vs Form.Close

The proper method would be Application.Exit(). According to the Documentation, it terminates all message loops and closes all windows thus giving your forms the possibility to execute their cleanup code (in Form.OnClose etc).

Environment.Exit would just kill the process. If some form has e.g. unsaved changes it would not have any chances to ask the user if he wants to save them. Also resources (database connections etc.) could not be released properly, files might not be flushed etc.

Form.Close just does what it says: it closes a form. If you have other forms opened (perhaps not now but in some future version of your application), the application will not terminate.

Keep in mind that if you use multithreading, Application.Exit() will not terminate your threads (and thus the application will keep working in the background, even if the GUI is terminated). Therefore you must take measures to kill your threads, either in the main function (i.e. Program.Main()) or when in the OnClose event of your main form.

How do I properly exit a C# application?

From MSDN:

Application.Exit

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.

Environment.Exit

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.

This article, Application.Exit vs. Environment.Exit, points towards 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) 
{
// WinForms app
System.Windows.Forms.Application.Exit();
}
else
{
// Console app
System.Environment.Exit(1);
}

Reference: Why would Application.Exit fail to work?

What is the difference between Environment.Exit(0) and Environment.Exit(Environment.ExitCode)?

I've used both, and they seem to do the same thing.

As others have already noted, that's because the default value for ExitCode is 0.

So which one should I use?

Typically, if you call Exit(), you a) have a good reason for that and b) you want to terminate as soon as possible with all the disadvantages described in the remarks section.

Therefore you would

  • never call Environment.Exit(0); and instead let the void Main() method run to its end in a normal way.
  • never call Environment.Exit(Environment.ExitCode); because that would imply that the reason for the termination was set a while back.
  • call Environment.Exit(ERRORCODE);, likely with a meaningful constant instead of a magic number

So the real answer is: don't use it at all, if possible.

Instead you might want to try Window.Close() to close a single window or Application.Exit(), which closes all windows and gets you back to the Main() method and out of the Application.Run() method call.

If that's not sufficient to terminate your program and you still see it in Task Manager, it has a foreground thread running, e.g. a thread that saves the users work. You don't want to terminate that, because it could result in a corrupted file.

There is a concept of a boolean isRunning or _shouldStop variable to terminate threads.

If you don't know why your application is not terminating, attach a debugger and have a look at the callstack of the remaining threads.

Application.Exit() vs Application.ExitThread() vs Environment.Exit()

Unfortunately, the problem isn't caused by any of these, and really exists (even if you don't get the message) in all of these scenarios.

Your problem is this:

On closing my WinForm App fires of a Form in Dialog mode. That form runs a Background worker that Syncs the DB with the remote DB and displays it's progress on the "Splash Form."

Since you're not actually shutting down when you request a shutdown, all of the "Exit" functions are trying to tear down your background thread. Unfortunately, this is probably happening in the middle of your DB sync, and an enumeration working in the save logic is probably providing that error.

I would recommend not using any of these - just call myMainForm.Close() instead. That should close your main form, which will fire your closing logic appropriately. Once the main form in your application closes, it will shut down gracefully.

Application.Exit Isn't closing my program, any alternatives?

You want:

Environment.Exit(0);

How to exit a Windows Forms Application in C#

You first need to quote your string so the message box knows what to do, and then you should exit your application by telling the application context to exit.

private void Defeat()
{
MessageBox.Show("Goodbye");
Application.Exit();
}

Winforms Application.Exit on Closing x app or clicking a Exit Button with a confirmation message

Thanks to nihique posted here https://stackoverflow.com/a/13459878/942855
and also pointed by MickyD in this question comments.

Apparently there is no issue with my closing event. When I redirect from Form-A to Form-B, I had to do the following wiring and then it worked like a charm

 var newform = new myNewForm();
newform.Closed += (s, args) => this.Close();
this.Hide();
newform.Show();

Whats the difference between these methods for closing my application?

If you are wanting to gracefully handle the exception in the last case, that's ok (not great though) - as long is it is an exceptional situation to your application. Otherwise I'd create a new method that shows the form as a dialog with a boolean. If the boolean comes back false (aka, user closed the form) I would then handle the application shut down from there (Using Application.Exit()).

It is, in my humble opinion, very bad practice to close the application from a child rather than telling the parent. The only time I agree with this is in a FailFast situation, which are very rare.


  • Application.Exit();

This method stops all running message loops on all threads and closes all windows of the application. This method does not force the application to exit. The Exit method is typically called from within a message loop, and forces Run to return. To exit a message loop for the current thread only, call ExitThread.

  • Application.ExitThread();

See above.


  • Environment.Exit(1);

Terminates this process and gives the underlying operating system the specified exit code.


  • Process.GetCurrentProcess().Kill();

Kill forces a termination of the process, while CloseMainWindow only requests a termination. When a process with a graphical interface is executing, its message loop is in a wait state. The message loop executes every time a Windows message is sent to the process by the operating system.


  • SFTPClient.LDAPLoggedIn = false; Close();

After the clarification in the comment (passes flow back to the parent and handles from there), this is by far the best way of doing this.


  • throw new Exception("User closed the form");

Throws an exception to the calling process. If this is the main thread, it will throw the exception in a very ugly way.

.NET End vs Form.Close() vs Application.Exit Cleaner way to close one's app

The situation you describe is pretty fishy. Whenever you close your program's startup form, the entire application should quit automatically, including closing all other open forms. Make sure that you're closing the correct form, and you should not experience any problems.

The other possibility is that you've changed your project (using its Properties page) not to close until all open windows have been closed. In this mode, your application will not exit until the last remaining open form has been closed. If you've chosen this setting, you have to make sure that you call the Close method of all forms that you've shown during the course of application, not just the startup/main form.

The first setting is the default for a reason, and if you've changed it, you probably want to go fix it back.

It is by far the most intuitive model for normal applications, and it prevents exactly the situation you describe. For it to work properly, make sure that you have specified your main form as the "Startup form" (rather than a splash screen or log-in form).

The settings I'm talking about are highlighted here:

   Visual Studio Project Properties

But primarily, note that you should never have to call Application.Exit in a properly-designed application. If you find yourself having to do this in order for your program to close completely, then you are doing something wrong. Doing it is not a bad practice in itself, as long as you have a good reason. The other two answers fail to explain that, and thus I feel are incomplete at best.



Related Topics



Leave a reply



Submit