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

2019-01-17 10:03发布

问题:

I am trying to figure out which I should be using. 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."

I have a method like so:

private void CloseMyApp()
{
    SaveUserSettings();

    splashForm = new SplashForm();
    splashForm.ShowDialog();

    Application.ExitThread();
    //Application.Exit();
}

which is what I call to close my app from Menu --> Exit and in the Form_FormClosing() event. Application.Exit() gives the following error -->

Collection was modified; enumeration operation may not execute.

Now I read that Environment.Exit() is brutal and means there is probably something wrong with your app (see here).

Application.ExitThread() works but I am concered that it may only be APPEARING to work and as I have never used it before I am not sure when it is normally appropriate to do so.

回答1:

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.



回答2:

Environment.Exit() is used for console apps.

You want to use: System.Windows.Forms.Application.Exit()

By exiting thread, you are only exiting the current thread context, while leaving any started foreground threads running. I suspect the thread that is causing the error is still running, so you've essentially masked the problem, not worked around it. I would try and figure out why you are getting this error "Collection was modified; enumeration operation may not execute." on exit. It's being exposed by Application.Exit(), but it's not caused by it.