ChatGPT解决这个技术问题 Extra ChatGPT

How do I properly exit a C# application?

I have a published application in C#. Whenever I close the main form by clicking on the red exit button, the form closes but not the whole application. I found this out when I tried shutting down the computer and was subsequently bombarded by lots of child windows with MessageBox alerts I added.

I tried Application.Exit but it still calls all the child windows and alerts. I don't know how to use Environment.Exit and which integer to put into it either.

Also, whenever my forms call the FormClosed or FormClosing event, I close the application with a this.Hide() function; does that affect how my application is behaving?

Don't handle FormClosed or FormClosing
So you say you are only hiding the forms instead of closing them? That's probably the reason the application is not terminating, it still has open (hidden) forms.
Then I should replace all of the this.Hide() to this.Close()?
You don't need Hide() or Close().
Post the code concerning Close actions and events.

C
Community

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?


This was really useful for me as I had a WinForms app which had an argument so it could run silently and therefore did not show a form. When the form was hidden then Application.Exit() failed to exit the app, however Environment.Exit(1) worked like a charm.
The question didn't mention exiting due to an error, so the exit code should be zero: Environment.Exit(0) Any non-zero value is meant to be an application-specific error code that could be used by a script to take appropriate action. (This is new code and a WinForms application, so it is unlikely to matter in this case, but good to know for anyone writing command-line tools.)
Environment.Exit can be used for forms application too.
Correct me if I'm wrong but I think a return statement afterwards would improve this approach a lot. As I understood the code would continue execution after Application.Exit() till a return statement.
@Bighted19 really? can you elaborate on this mechanic?
S
Scott Chamberlain

I know this is not the problem you had, however another reason this could happen is you have a non background thread open in your application.

using System;
using System.Threading;
using System.Windows.Forms;

namespace Sandbox_Form
{
    static class Program
    {
        private static Thread thread;

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            thread = new Thread(BusyWorkThread);
            thread.IsBackground = false;
            thread.Start();

            Application.Run(new Form());

        }

        public static void BusyWorkThread()
        {
            while (true)
            {
                Thread.Sleep(1000);
            }
        }
    }
}

When IsBackground is false it will keep your program open till the thread completes, if you set IsBackground to true the thread will not keep the program open. Things like BackgroundWoker, ThreadPool, and Task all internally use a thread with IsBackground set to true.


S
Servy

By the way. whenever my forms call the formclosed or form closing event I close the applciation with a this.Hide() function. Does that affect how my application is behaving now?

In short, yes. The entire application will end when the main form (the form started via Application.Run in the Main method) is closed (not hidden).

If your entire application should always fully terminate whenever your main form is closed then you should just remove that form closed handler. By not canceling that event and just letting them form close when the user closes it you will get your desired behavior. As for all of the other forms, if you don't intend to show that same instance of the form again you just just let them close, rather than preventing closure and hiding them. If you are showing them again, then hiding them may be fine.

If you want to be able to have the user click the "x" for your main form, but have another form stay open and, in effect, become the "new" main form, then it's a bit more complicated. In such a case you will need to just hide your main form rather than closing it, but you'll need to add in some sort of mechanism that will actually close the main form when you really do want your app to end. If this is the situation that you're in then you'll need to add more details to your question describing what types of applications should and should not actually end the program.


A
Anton Tsches

In this case, the most proper way to exit the application in to override onExit() method in App.xaml.cs:

protected override void OnExit(ExitEventArgs e) {
    base.OnExit(e); 
}

That allows you to execute code whenever an exit event happens, but does not actually cause the exit event to happen.