Application.restart - Puzzling behaviour in VB.Net
vb.net
Solution
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` is `Nothing`, throwing a `NotSupportedException` if it is;
- the `Process.GetCurrentProcess.MainModule.FileName` is `ieexec.exe` in the same folder as the current .NET Framework (specifically the folder where the module defining `Object` is);
- `ApplicationDeployment.IsNetworkDeployed` is `True`; 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`).
Problem
OK guys, what's going on here? In this VB code: ``` Module Module1 Sub Main() If MsgBox("Restart?", MsgBoxStyle.OkCancel) = MsgBoxResult.Ok Then Application.Restart() MsgBox("restarting") Else MsgBox("Cancel") End If End Sub End Module ``` If this code is contained within a module, Application.Restart does not end the running application till the End Sub is hit. Any code that appears before then is executed - eg the 'Restarting' messagebox appears. However, if the equivalent code is run within a form then Application.Restart terminates the running application immediately. (Both cases correctly start a new instance). This behaviour does not appear to be documented anywhere - the implication in the docs is that it's synonymous with 'End' as far as the termination of the running instance is concerned. Am I missing something?