为什么我不应该使用 Process.GetCurrentProcess().Kill() 退出我的 WinForm 应用程序?
现在,当用户想要退出我的应用程序时,我必须执行一些操作(即与服务器断开连接、保存用户数据...),然后执行以下操作:
- 使用布尔值退出所有主循环
- 中止仍在运行的线程(通常是我的服务器轮询线程)
- 请调用 Application.Exit();
这需要几秒钟才能退出,并且没有任何实际目的(所有内容都已经保存在服务器上,所以我并不关心那里发生了什么)
如果我使用它,我会立即终止,没有任何我能想到的缺点:
System.Diagnostics.Process.GetCurrentProcess().Kill();
为什么我不直接终止我的进程并让 CLR 删除 AppDomain ?
我知道仔细处理你的共享资源(IO 文件处理程序等)很重要(所以请不要回答这个问题:)),但是一旦完成,是否有真正的理由干净地退出我的应用程序?
Right now, when the user want to exit my application, I do the few things I have to (ie disconnecting from the server, saving the user data...) and then I do the following :
- Exit all my mainloops using booleans
- abort the threads still running (typically, my server polling thread)
- kindly call Application.Exit();
This takes a few seconds to exit, and serves no real purpose (everything is already saved on the server, so I don't really care what happens there)
If I use this instead, I got instant termination with no drawback I can think of :
System.Diagnostics.Process.GetCurrentProcess().Kill();
Why wouldn't I just terminate my process and let the CLR drop the AppDomain ?
I know that carefully disposing your shared resources (IO file handlers, etc.) is important (so please don't answer that:)), but once it's done, is there a real reason to cleanly exit my App ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
终止进程意味着finally块将不会被执行,甚至可能不会关键终结器对象,实际上可能很关键,并会导致系统级别的资源泄漏。 当其他人维护代码时,它还可能在将来导致意想不到的错误,因为他们(或你)将不得不绞尽脑汁,每次编写finally块时都必须考虑它是否会被执行。
Killing the process would mean that finally blocks will not be executed, and probably not even critical finalizer objects, which may actually be critical, and cause resource leakage at system level. It can also cause unexpected bugs in the future when someone else maintains the code, as they (or you) will have to twist their heads, having to think every time they write a finally block whether it will be executed.
这确实是个好问题!
很久以前(十多年前),我编写了一个 VB6 应用程序,由于 WinINet OCX(或无论它被称为什么)中的一个已确认的错误(由于它正在通信的 Web 服务器上使用的特定证书)而在终止时挂起。
由于没有任何方法来解决这个错误,我使用了 TerminateProcess,据我所知,这个应用程序已经在数千台机器上使用了好几年,而且我从未听说过有关此黑客攻击的任何问题!
That's indeed a good question!
Once upon a time (over ten years ago) I wrote a VB6 app wich hung at termination due to a confirmed bug in the WinINet OCX (or whatever it was called) due to the particular certificate used on a web server it was talking to.
Without any way to come around this bug I used TerminateProcess and for all that I know, this app was in use on several thousand machines for several years and I never heard of any problem regarding this hack!
首先,我认为您的意思是
Process.Kill()
,而不是Process.TerminateProcess()
。 其次,终止进程只会将其撕掉。 任何清理代码都不会执行,您的应用程序将没有机会取消终止(例如,如果用户有未保存的数据)。 如果你对此感到满意,那就去吧。Firstly, I think you mean
Process.Kill()
, notProcess.TerminateProcess()
. Secondly, killing the process will just rip it out. Any cleanup code will not execute and your application will not get a chance to cancel the kill (eg. if the user has unsaved data). If you're happy with that, go for it.请记住,如果您正在写入文件/网络流,则写入可能不完整。
如果您的应用程序已准备好以这种方式处理损坏的数据,那么没有理由不这样做。 但是,如果您可以通过其他方式退出,我建议您这样做。
Keep in mind that if you are writing to a file/network stream it's possible that your write will be imcomplete.
If your application is ready to deal with corrupt data in that way, then there's no reason not to do it. However, if you can exit by other means I'd recommend that.
应该注意的是,终结器实际上可能永远被执行 ,因此终止进程与跳过终结代码的任何其他原因没有太大区别,例如缓慢的终结器或引发异常的终结器。
总而言之,我不会太担心关闭应用程序需要几秒钟的时间,特别是如果它立即隐藏所有窗口并为用户“消失”。 但是,如果关闭需要数十秒和/或用户可能再次执行应用程序并且它不支持多个实例,则调用 Process.Kill 可能是一个好主意。
我知道一些应用程序需要很长时间才能终止,我希望有一天看到它们残酷地自杀,而不是让我,用户,这样做(这在操作系统重新启动时尤其烦人)。
It should be noted that finalizers may actually be never executed, so killing the process is not much different from any other reason to skip finalization code, like slow finalizers or a finalizer throwing an exception.
All in all, I wouldn't worry much about closing the application taking a few seconds, especially if it immediately hides all its windows and "disappears" for the user. However, if closing takes dozens of seconds and/or the user is likely to execute the application again and it doesn't support multiple instances, calling
Process.Kill
may be a good idea.I know some applications which take ages to terminate, and I hope to see them one day just brutally killing themselves rather than making me, the user, do it (it's especially annoying on OS restart).
使用无法捕获错误或泄漏的第三方库,有时结束它而不引发崩溃 MessageBox 的唯一方法是终止进程。
Using Third party libraries with no way to catch their errors or leaks, sometimes the only way to end it without throwing up a crash MessageBox, is to Kill the process.
为什么不使用 System.Environment.Exit(int)? 看起来您只想这样做只是为了节省代码。 对我来说,更清楚地看到对 Exit 的调用确实如此,并且您的关闭将受到更多控制,终结器和关键终结器将运行。
Why not use System.Environment.Exit(int)? It seems like you want to do this just to save code. To me it's much clearer to see the call to Exit does and your shutdown will be more controlled, Finalizers and Critical Finalizers will run.