管理 .NET 应用程序在终止/终止时正常关闭
我们有一个具有许多前台线程的 .NET 控制台应用程序。 如果我们使用任务管理器终止进程或从 Windows 命令行中发出killjob、kill,是否有一种方法可以优雅地关闭应用程序(在 .net 控制台应用程序中添加托管代码),例如拥有一个函数被调用说 TodoBeforeShutdown() 处理对象,关闭任何打开的连接等。
PS - 我阅读了其他线程,他们都建议了不同的方法来终止进程,而不是我的具体问题,我们可以处理的最佳方法是什么在 .NET 托管代码中终止进程。
提前致谢。
We have a .NET console app that has many foreground threads.
If we kill the process using Task Manager or issuing killjob, kill from the command line in windows, is there a way by which we can gracefully shut down the application (adding manged code within the .net console app), something like having a function being called say TodoBeforeShutdown() that disposes objects, closes any open connections, etc.
P.S. - I read the other threads and they all suggested different ways to kill the process, rather than my specific question, what is the best way we can handle a terminate process, within the .NET managed code.
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不幸的是,每当进程被终止时,都不会引发您可以处理的事件。
您可以将终止进程想象成切断计算机电源 - 无论您设计了什么代码要在系统关闭时运行,如果计算机没有正常或正确关闭,该代码将不会运行。
当您使用任务管理器终止进程时,它会调用 Win32 < code>TerminateProcess 函数,无条件强制进程(包括其拥有的所有线程)退出。 所有线程/进程的执行都会停止,并且所有挂起的 I/O 请求都会被取消。你的程序实际上已经死了。
TerminateProcess
函数不会调用 CLR 提供的关闭序列,因此您的托管应用程序甚至不知道正在关闭。您建议您“当您的应用程序进程终止时,您会担心处理对象,但这里有一些值得指出的事情:
始终努力将可能造成的损害降到最低。当您用完物品后,请尽早处理掉它们。不要等到以后。在任何给定时间,当程序进程终止时,您应该只保留最少数量的对象,这样会减少泄漏的可能性。
操作系统通常会在终止时清理并释放大部分这些资源(即句柄等)。
最后,不用说,以这种方式终止进程确实是一种例外情况 - 即使某些资源泄漏,这是可以预料的。您不应该以这种方式关闭应用程序,就像您不应该终止必要的 Windows 系统进程一样(即使您可以以管理员身份运行)。
如果这是您关闭控制台应用程序的常规计划,您需要寻找其他计划。
Unfortunately, there is no event raised that you can handle whenever a process is killed.
You can think of killing a process like cutting off the power to the computer—no matter what code you have designed to run on system shutdown, if the computer doesn't shut down gracefully or properly, that code is not going to run.
When you kill a process using Task Manager, it calls the Win32
TerminateProcess
function, which unconditionally forces the process (including all of its owned threads) to exit. The execution of all threads/processes is halted, and all pending I/O requests are canceled. Your program is effectively dead. TheTerminateProcess
function does not invoke the shutdown sequence provided by the CLR, so your managed app would not even have any idea that is was being shut down.You suggest that you're concerned about disposing objects whenever your application's process is terminated, but there are a couple of things worth pointing out here:
Always strive to minimize the amount of damage that could be done. Dispose of your objects as early as possible, whenever you are finished with them. Don't wait until later. At any given time, when your program's process is terminated, you should only be keeping the bare minimum number of objects around, which will leave fewer possibilities for leaks.
The operating system will generally clean up and free most of these resources (i.e., handles, etc.) upon termination.
Finally, it should go without saying that process termination in this way is truly an exceptional condition—even if some resources leak, that's to be expected. You're not supposed to shut an app down this way any more than you're supposed to kill necessary Windows system processes (even though you can when running as an Administrator).
If this is your regular plan to shut down your console application, you need to find another plan.
简而言之:你不能!
终止进程与正常退出完全相反。
如果您正在运行前台线程,发送 wm_exit 不会关闭您的应用程序。由于您有一个控制台应用程序,您可以简单地重定向控制台输入以将“退出”发送到您的进程。
此外,我认为您可以将应用程序更改为服务(而不是控制台应用程序),这将为您提供准确的服务您正在寻找什么 ->基于 Windows 内置工具/命令的正常退出界面。
In short: You can't!
Killing a process is exactly the opposite of a gracefull exit.
If you are running Foreground Threads, sending a wm_exit won't shut down your app. Since you have a console app, you could simply redirect the console input to send an "exit" to your process.
Further I think you could change the app to service (instead of a console application), this would offer you exactly what you are looking for -> interface for gracefull exit based on windows build-in tools/commands.