Application.restart - Puzzling behaviour in VB.Net
The best way to answer these questions it to look at the code itself using Reflector (or Microsoft's free for debugging code, when it is available).
With Reflector, you can see (in .NET Framework 4.0) System.Windows.Forms.Application.Restart
looks for four different types of applications:
- the initial check that
Assembly.GetEntryAssembly
isNothing
, throwing aNotSupportedException
if it is; - the
Process.GetCurrentProcess.MainModule.FileName
isieexec.exe
in the same folder as the current .NET Framework (specifically the folder where the module definingObject
is); ApplicationDeployment.IsNetworkDeployed
isTrue
; and- the general case.
All three supported cases determine the method to start the process again, calls Application.ExitInternal
and starts the process again.
Application.ExitInternal
closes open forms, including the check for a form attempting to abort the close by setting FormClosingEventArgs.Cancel
to True
. If no form attempts to cancel, the forms are closed and, using ThreadContext.ExitApplication
, all ThreadConnexts
are cleaned up (Disposed
or their ApplicationContext.ExitThread
is called).
NB No Thread.Abort
is called, so threads are NOT explicitly ended in any way. Also the Windows.Forms
ModalApplicationContext
, does not even call the ThreadExit
"event" that a normal ApplicationContext
does.
(Note that all three supported cases in Application.Restart
ignore the result of Application.ExitInternal
, so if a form does attempt to abort all that happens is any other forms don't get a chance to close, and the ThreadContexts are not cleaned up!)
Importantly for your question, it does NOT attempt to actually exit the current threads or the entire application (other than closing open forms and thread contexts).
However, by the time your MsgBox("restarting")
executes the new application has been started.
You need to manually exit the application after calling Application.Restart
. In the case of "run[ing] within a form" (you don't show the code where you tested this) either the form is closed and that is what you considered as the current application ending, or extra stuff that Windows.Forms
(or VB) sets up means the application is exited by one of the "events" that throw when the clean up that does occur runs.
In other words, before testing it I expected the MsgBox
to appear even when this code is in say the Click
event of a form, with the form disappearing first, and the application restarting at the same time.
Having tested it, the MsgBox
tries to appear, as I hear the beep that corresponds to it, and if I comment it out the beep does not occur. So something causes the application to exit even though it should have a message box open, and even putting a MsgBox
in a Finally
outside of the Application.Run
does not appear on a Restart
. (Note a similar effect is seen if you call MsgBox
after Application.Exit
.)
So something set up by Windows.Forms
(or VB) does actually call something like Environment.Exit
which calls the Win32Api ExitProcess
and does not regard Finally
or call Dispose
or Finalize
.
Note the Application.Restart
documentation implies it is not for Console Applications though it currently works fine (except for the not quitting straight away, which is not implied by Application.Exit
).