tags:

views:

164

answers:

3

Basically I have a main form which upon loading, opens a child form for logging in the user. When they cancel or close this login form, I need to close the whole application.

But there seems to be a few different ways to close a C# program:

  1. Application.Exit();

  2. Application.ExitThread();

  3. Environment.Exit(1);

  4. Process.GetCurrentProcess().Kill();

  5. SFTPClient.LDAPLoggedIn = false; Close();

EDIT: Sorry if this one is not clear: It sets a property in a controller object to indicate that the login failed. After opening the child form, I would check this property in the parent form to see whether the program should continue or not. It basically shifts the responsibility of exiting the program to the parent without an exception.

6: throw new Exception("User closed the form");

I can see that there are two ways of handling it:

  • Informing the parent that something went wrong (as in 5 and 6.)
  • Closing the program from the child form.

Is either of these two considered better practice?

Each approach seems to have the same effect on my program but how do they actually compare?

UPDATE: Thanks for the answers. For those searching this question in the future and curious people, this was my solution in the end:

private void FormMain_Load(object sender, EventArgs e)
{
    if (new FormLogin().ShowDialog(this) == DialogResult.Cancel) Close();
}

and:

private void buttonCancel_Click(object sender, EventArgs e)
{
    Close();
}

I discovered that when a form is closed via clicking the 'X', DialogResult is set to Cancel automatically so all I need to do is Close()

+2  A: 

You should use Form.Close() as opposed to Application.Exit. As the MSDN documentation notes, events like Form.Close and Form.Closing don't fire when you use Application.Exit.

msergeant
OK, I can see the advantage to that. So should `Application.Exit` be called from Program.cs after each form has been `Close` d?
rmx
No reason to. Your process will end if you've exited child threads and your main function returns (ending the main thread). If you want to provide a return code which may be of interest to the process that launched yours, use `Environment.Exit(retcode)` at the end of your main function.
Ben Voigt
+9  A: 

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.

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.

See above.

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

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.

Kyle Rozendo
Sorry about the formatting edit war :/
Jon B
@Jon - No problem, was busy adding to the answer, hehe. Thanks for the edit though, my initial one screwed up.
Kyle Rozendo
SO needs a CMM edit model. **Now.**
BoltClock
Sorry - to clarify #5. It sets a property in a controller object to indicate that the login failed. After opening the child form, I would check this property in the parent form to see whether the program should continue or not. It basically shifts the responsibility of exiting the program to the parent without an exception.
rmx
@rmx - DEFINITELY #5 then, without a doubt.
Kyle Rozendo
Thanks for the answers, much appreciated :-)
rmx
+4  A: 

All this ways for terminating application are too complex and they useful in different scenarios, but not in yours.

You may slightly redesign your application to solve you problem in more elegant way. In main method you may show login form and if users click "cancel" button, then you simply exit from your main method. Otherwise you show you main form:

class Program {
  static void Main(String[] args) {
     if ( Login.Show() ) {
        //Show main form for your application
     }
     //otherwise you simply return from Main method
  }
}

This behaviour more clear and simple. And in most cases main form is too hevyweight, so your user should wait more time to see first window from your app.

Sergey Teplyakov
+1 Almost exactly what I am saying, with code.
Kyle Rozendo