.net 为什么不应该';我是否使用Process.GetCurrentProcess().Kill()退出我的WinForm应用程序?

.net 为什么不应该';我是否使用Process.GetCurrentProcess().Kill()退出我的WinForm应用程序?,.net,termination,.net,Termination,现在,当用户想要退出我的应用程序时,我会做一些必须做的事情(即断开与服务器的连接,保存用户数据…),然后执行以下操作: 使用布尔值退出所有主循环 中止仍在运行的线程(通常是我的服务器轮询线程) 请致电Application.Exit() 这需要几秒钟的时间才能退出,并且没有任何实际用途(所有内容都已保存在服务器上,因此我并不真正关心那里发生了什么) 如果我改用这个,我可以立即终止,我想不出任何缺点: System.Diagnostics.Process.GetCurrentProcess(

现在,当用户想要退出我的应用程序时,我会做一些必须做的事情(即断开与服务器的连接,保存用户数据…),然后执行以下操作:

  • 使用布尔值退出所有主循环
  • 中止仍在运行的线程(通常是我的服务器轮询线程)
  • 请致电Application.Exit()
这需要几秒钟的时间才能退出,并且没有任何实际用途(所有内容都已保存在服务器上,因此我并不真正关心那里发生了什么)

如果我改用这个,我可以立即终止,我想不出任何缺点:

 System.Diagnostics.Process.GetCurrentProcess().Kill();
为什么我不能终止进程,让CLR删除AppDomain


我知道小心地处理共享资源(IO文件处理程序等)很重要(所以请不要回答:),但一旦完成,有没有真正的理由彻底退出我的应用程序?

首先,我想你的意思是
Process.Kill()
,而不是
Process.TerminateProcess()
。其次,扼杀进程只会将其撕毁。任何清理代码都不会执行,应用程序也不会有机会取消清除(例如,如果用户有未保存的数据)。如果你对此感到满意,那就去做吧。

这的确是个好问题

曾几何时(十多年前),我编写了一个VB6应用程序,由于WinINet OCX(或任何它被称为的东西)中的一个已确认的错误,该错误在终止时被挂起,原因是与它对话的web服务器上使用了特定的证书


我使用TerminateProcess解决了这个bug,据我所知,这个应用程序在几千台机器上使用了好几年,我从来没有听说过关于这个黑客的任何问题

请记住,如果您正在写入文件/网络流,那么您的写入可能会不完整


如果您的应用程序已经准备好以这种方式处理损坏的数据,那么没有理由不这样做。但是,如果您可以通过其他方式退出,我建议。

终止进程将意味着最终块将不会执行,甚至可能不会执行,这实际上可能很关键,并导致系统级的资源泄漏。将来当其他人维护代码时,它也可能导致意外的错误,因为他们(或您)将不得不绞尽脑汁,每次编写finally块时都必须考虑是否会执行它。

为什么不使用?看起来您这样做只是为了保存代码。对我来说,更清楚的是,调用Exit确实可以控制您的关闭,终结器和关键终结器将运行。

应该注意的是,终止进程与跳过终结代码的任何其他原因没有太大区别,比如速度慢的终结器或引发异常的终结器

总而言之,我不太担心在几秒钟内关闭应用程序,尤其是当它立即隐藏所有窗口并为用户“消失”时。但是,如果关闭需要几十秒,并且/或者用户可能会再次执行应用程序,并且它不支持多个实例,那么调用
Process.Kill
可能是一个好主意


我知道有些应用程序需要很长时间才能终止,我希望有一天他们会残忍地自杀,而不是让我这个用户这么做(在重新启动操作系统时,这尤其令人恼火)。

使用第三方库无法发现错误或泄漏,有时,在不抛出崩溃消息框的情况下结束它的唯一方法是终止进程。

我想在这种情况下,任何finally块都不会被处理,这可能会在将来其他人维护代码时导致意外的错误。@Hosam:这是一个很好的观点。你为什么不把它作为一个答案贴出来,这样就可以投票了?@Brann:好了。谢谢你的建议。实际上是Process.GetCurrentProcess().Kill();我相应地调整了我的职位。谢谢你注意到了!:)操作系统不应该仅仅因为进程被终止而泄漏资源。但这些最终块和终结器是一个很好的观点。@Qwertie是的,但有时确实如此。例如,即使应用程序崩溃,相机也可能保持打开状态。这可能是驱动程序中的一个bug,但这也是“系统”的一部分。然而,我现在有一个测试用例,在Kill hack中失败了。这是一个充满骰子的过程,确切地说是什么时候被终止的,确切地说是进程在做什么,确切地说是应该发生什么。这就是为什么ACID数据库要花费巨大的时间来确保数据的写入/可重放性——以便它们可以在任何时候被粗暴地关闭,而不会丢失数据。如果卡住的进程正在使用关键数据(当时或以后)进行下蹲操作,那么一定要使用核武器;它实际上与通过process explorer终止进程没有什么不同。如果底层appdomain或本机代码跳入WER/ReportFault函数族,则Environment.Exit(int)不保证退出。即使Kill()也不能保证终止,因为内核级死锁会阻止进程退出,但Kill通常会立即终止,而Exit允许程序进行清理。