Application.restart - VB.Net 中令人费解的行为 [英] Application.restart - Puzzling behaviour in VB.Net

查看:25
本文介绍了Application.restart - VB.Net 中令人费解的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的伙计们,这是怎么回事?在这个 VB 代码中:

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

如果此代码包含在模块中,Application.Restart 不会结束正在运行的应用程序,直到 End Sub 被点击.在此之前出现的任何代码都会被执行——例如,出现正在重新启动"消息框.但是,如果等效代码在表单中运行,则 Application.Restart 会立即终止正在运行的应用程序.(两种情况都正确启动了一个新实例).这种行为似乎没有记录在任何地方 - 文档中的含义是,就正在运行的实例的终止而言,它与结束"同义.我错过了什么吗?

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?

推荐答案

回答这些问题的最佳方法是使用 Reflector(或 Microsoft 的免费调试代码,如果可用)查看代码本身.

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).

使用 Reflector,您可以看到(在 .NET Framework 4.0 中)System.Windows.Forms.Application.Restart 查找四种不同类型的应用程序:

With Reflector, you can see (in .NET Framework 4.0) System.Windows.Forms.Application.Restart looks for four different types of applications:

  • 初始检查 Assembly.GetEntryAssembly 是否为 Nothing,如果是则抛出 NotSupportedException
  • Process.GetCurrentProcess.MainModule.FileNameieexec.exe 与当前 .NET Framework 相同的文件夹(特别是定义 的模块所在的文件夹)对象是);
  • ApplicationDeployment.IsNetworkDeployedTrue;和
  • 一般情况.
  • 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.

所有三种支持的情况决定了再次启动进程的方法,调用Application.ExitInternal并再次启动进程.

All three supported cases determine the method to start the process again, calls Application.ExitInternal and starts the process again.

Application.ExitInternal 关闭打开的表单,包括通过将 FormClosingEventArgs.Cancel 设置为 True 来检查尝试中止关闭的表单.如果没有表单尝试取消,则关闭表单,并使用 ThreadContext.ExitApplication 清除所有 ThreadConnexts(Disposed 或它们的 ApplicationContext.ExitThread 被调用).

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).

注意没有Thread.Abort 被调用,所以线程NOT 以任何方式明确结束.此外,Windows.Forms ModalApplicationContext 甚至不会像普通的 ApplicationContext 那样调用 ThreadExit 事件".

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.

(注意,Application.Restart 中的所有三种情况都支持忽略Application.ExitInternal 的结果,所以如果一个表单尝试中止发生的所有事情是任何其他形式都没有机会关闭,并且 ThreadContexts 没有清理!)

(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).

但是,当您的 MsgBox("restarting") 执行时,新应用程序已经启动.

However, by the time your MsgBox("restarting") executes the new application has been started.

调用Application.Restart后需要手动退出应用程序.在在表单中运行[ing]"的情况下(您没有在测试此代码的地方显示代码)要么表单已关闭,这就是您认为当前应用程序结束的内容,或者 的额外内容Windows.Forms(或 VB)设置意味着应用程序被其中一个事件"退出,这些事件"在确实发生的清理运行时抛出.

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.

换句话说,在测试它之前,我希望 MsgBox 出现,即使此代码在表单的 Click 事件中,表单首先消失,并且应用程序同时重新启动.

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.

经过测试后,MsgBox 尝试出现,因为我听到了与其对应的哔哔声,如果我将其注释掉,则不会出现哔哔声.所以有些事情会导致应用程序退出,即使它应该打开一个消息框,甚至将 MsgBox 放在 Application.RunFinally 中code> 不会出现在 Restart 上.(请注意,如果在 Application.Exit 之后调用 MsgBox 会看到类似的效果.)

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.)

所以由 Windows.Forms(或 VB)设置的东西实际上调用了类似 Environment.Exit 的东西,它调用了 Win32Api ExitProcess 和不考虑Finally 或调用DisposeFinalize.

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.

请注意 Application.Restart 文档暗示它不适用于控制台应用程序,尽管它目前工作正常(除了不会立即退出,Application.Exit 没有暗示)代码>).

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).

这篇关于Application.restart - VB.Net 中令人费解的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆