When I read the docs on MSDN for Application.Exit(), it says:
Informs all message pumps that they must terminate, and then closes all application windows after the messages have been processed.
In my understanding, to inform all message pump to terminate, this method would finally post a WM_QUIT message to the application message queue. And after posted the message, the method then would close each window(by MSDN). The problem is arising here, when this method try to close each window, the WM_QUIT message should have not been processed, but the MSDN said “it closes all windows after the messages have been processed”.
It seems the documentation is contradictory to my inference. What is the problem here, any help is greatly appreciated.
Interesting question; using ILSpy, let’s have a look at what
Application.Exit()does:We see that the critical method is
ExitInternalIf everything goes well, the application will first close all forms, then close any forms it missed, and then, finally, it calls
Application.ThreadContext.ExitApplication();As part of ExitApplication, we see the cleanup:
What does ExitThreadCore do?
Well, it doesn’t directly kill the thread, but it does start the process:
However, the really interesting bit seems to happen in
array[i].Dispose(disposing)As part of this method, we see:
PostQuit() is what sends the
WM_QUITmessage. So we should also consider whenApplication.ThreadContext.Disposeis called, and it is always seems to be after the forms have closed, although I’m happy to be corrected there.So the order seems to be close all forms, then send the WM_QUIT message. I think you are right, the documentation may actually have the events in the wrong order…
It also confirms another side effect we often see; when an application is closed but there is still a thread running in the background, the exe will still be in the list of running applications. The forms have been closed, but there is still that rogue thread, humming along preventing the Exit() from completing.
As Tergiver mentions:
(from Thread.IsBackgroundThread)
I also wondered what
Environment.Exitdoes:It effectively calls out to the OS to kill the process; this will terminate all windows with little grace; the OnFormClosing will probably never get to fire for example. As part of this wholesale termination, it will also [I hesitate to use attempt as I’ve never seen it fail] kill any threads including the ‘main’ thread the message loop is running on.