如何正确终止一个应用程序?

How to correctly terminate an application?

过去,我通常会在 KeyDown 子程序中添加以下行以结束我的应用程序:

If e.KeyCode = Keys.Escape Then End

但是,在阅读有关 End 实际操作的文档后,发现它可能是在释放资源等方面结束应用程序的最糟糕的方法之一。

所以现在我正在尝试找到终止应用程序的推荐方法,它将正确处理所有资源等。我在 SO 上发现了这两个问题(herehere) 但我无法断定正确答案到底是什么。

first link 上接受的答案说,将 Close() 应用于所有表单是正确的方法,并且会释放所有正确使用的资源。这在有多个表单的应用程序中不方便,建议再往下Application.Exit(),甚至:

Application.Exit()
End

这肯定会确保程序结束,即使第一行失败。

另一方面,second link 上接受的答案是“您永远不必在设计合理的应用程序中调用 Application.Exit()” ,与上述内容相矛盾,下面的答案说 Application.Exit() 在更高版本的 .Net 中对所有形式调用 Close()

这让我感到困惑 — Application.Exit() 有什么问题?

如果没有问题,那么我认为最好的是:

Application.Exit()
End

或者是做得太过分了?否则,Application.Exit() 何时无法工作(除非我编写取消它的代码)?

注意:虽然这个问题适用于我制作的所有程序,包括具有多种形式的程序,但我最近开始使用套接字(使用 TcpClient/Listener 类)在计算机之间建立连接并且会在连接中间终止程序时,请注意与此相关的任何其他信息。我的 recent question 中的评论向我保证甚至不需要调用 Socket.Close(),但现在我意识到这可能不完全正确,因为我之前使用 End 终止。

Application.Exit 向该应用程序的所有消息循环发布一条退出消息。

这是一种完全可以接受的关闭应用程序的方式,并且会导致所有表单尝试关闭。个别表单可以覆盖此行为,例如,如果它们有未保存的工作。这将在之后离开您的应用程序 运行,因此您需要决定是否需要处理它。

说我只在外部参与者需要关闭我的应用程序时才使用它。否则我会让应用程序在主窗体关闭时退出。

您还需要考虑您拥有的任何前台线程的状态,因为它们可以让您关闭所有表单,但将线程处理留在后台。

End 是一种非常强力的技术,应该作为最后的手段使用。一个设计良好的应用程序应该能够通过关闭窗体或调用 application.exit 来关闭。我过去使用过这种方法来启动一个定时器,它会在我调用 Application.Exit 之前调用 End ......至少我给了它一个优雅完成的机会。

注意:Application.Exit不阻塞。所以 Application.Exit : End 也可能是 End 这并不理想。

这是我使用的定时器:

    Dim forceExitTimer = New Threading.Timer(Sub() End, Nothing, 2500, Timeout.Infinite)
    Application.Exit()