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

3

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

If e.KeyCode = Keys.Escape Then End

然而,阅读了有关 End 实际操作的文档后,它可能是释放资源等方面最糟糕的应用程序终止方式之一。

因此,现在我正在尝试找到推荐的方法来终止应用程序,以正确处理所有资源等。我在这里找到了这两个问题 (herehere) ,但我无法得出正确的答案。

第一个链接上的 接受的答案说将 Close() 应用于所有窗体是正确的方法,并且会正确释放使用的所有资源。但是,在拥有多个窗体的应用程序中并不方便,甚至建议使用 Application.Exit(),甚至:

Application.Exit()
End

即使第一行失败,也可以确保程序结束。

另一方面,在第二个链接上的被接受的答案说“在设计良好的应用程序中,您永远不需要调用 Application.Exit()”,这与上述回答和下面的一个答案相矛盾,后者说 Application.Exit() 在较新版本的 .Net 中调用了所有窗体上的 Close()

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

如果没有问题,那么我是否正确地认为最好使用以下方法:

Application.Exit()
End

或者这样做有点过头了吗?否则,除非我编写取消它的代码,否则什么时候会导致Application.Exit()无法正常工作?
注意:虽然这个问题适用于我所做的所有程序,包括具有多个表单的程序,但我最近开始使用套接字(使用TcpClient/Listener类)在计算机之间建立连接,并且在终止连接期间终止程序时,我会感激任何与此相关的附加信息。我在我的最近的问题中得到了一个评论,保证调用Socket.Close()甚至不是必要的,但现在我意识到,在之前我使用End来终止连接时,这可能并不完全正确。

3
但现在我意识到这可能并不完全正确,因为之前我一直在使用 End 来终止程序。如果调用 End,程序将立即被终止,没有优雅的垃圾回收(所有资源将由操作系统释放)。因此,如果想要连接优雅地关闭,更或者说你必须调用 Socket.Close()但是,如果使用 End,也存在可能在套接字处理完成之前就提前终止执行的风险。因此,不推荐在应用发布时使用 End,仅在调试时使用。 - Visual Vincent
@VisualVincent 谢谢,我想我会避免使用 End。顺便问一下,为什么修改问题?这只适用于 .net 吗? - Shuri2060
1
我从标题中删除了“VB”,因为这是不必要的,并且建议不要在标题中写入您的语言或标签。使用“vb.net”标记问题已足够,因为它已经表明了您使用的语言。请参见:问题标题应包含标签吗? - Visual Vincent
2
@VisualVincent 好的,谢谢,我会记住的。 - Shuri2060
1个回答

3

Application.Exit会将退出消息发布到该应用程序的所有消息循环中。

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

我只在外部操作需要关闭我的应用程序时才使用它。否则,当其主窗体关闭时,我让应用程序退出。

您还需要考虑您拥有的任何前台线程的状态,因为这些线程可以允许关闭所有窗体,但将处理留在后台。

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

注意:Application.Exit不会阻塞。因此,Application.Exit: EndEnd可能一样,这并不理想。

以下是我使用的计时器:

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

谢谢!我刚刚尝试搜索,但没有结果:如果您没有编写任何明确停止此操作的代码,Application.Exit()是否会失败关闭应用程序? - Shuri2060
是的。在其FormClosing事件中,表单可以阻止它关闭。如果您不终止线程,它们也可以保持其开放状态。这主要是发出应用程序优雅关闭的信号,由开发人员负责实现,但并不太困难。请看我的关于退出定时器的说明,它将确保应用程序最终关闭。 - FloatingKiwi
顺便问一下,如果我不处理它们,甚至由任务创建的线程也会阻止它关闭吗? - Shuri2060
不会,它们是后台线程,因此不会阻塞关闭。因此我如何在我的示例中使用forceExitTimer - FloatingKiwi
你不一定需要这样做,但在关闭之前尝试处理掉你使用的任何东西始终是最佳实践。 - FloatingKiwi
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接