管理.NET应用程序以在终止/终止时正常关闭

时间:2010-11-24 11:59:32

标签: .net process kill handle

我们有一个.NET控制台应用程序,它有许多前台线程。 如果我们使用任务管理器终止进程或发出killjob,从windows中的命令行执行kill,有没有办法可以优雅地关闭应用程序(在.net控制台应用程序中添加manged代码),比如有一个函数被称为TodoBeforeShutdown(),用于处理对象,关闭所有打开的连接等。

P.S。 - 我读了其他线程,他们都提出了不同的方法来杀死进程,而不是我的具体问题,在.NET托管代码中,我们可以处理终止进程的最佳方式是什么。

提前致谢。

2 个答案:

答案 0 :(得分:10)

不幸的是,没有任何事件可以处理,只要一个进程被杀死就可以处理。你可以想到杀掉像切断电脑电源这样的过程 - 不管是什么您设计为在系统关闭时运行的代码,如果计算机没有正常或正常关闭,该代码将无法运行。

当您使用任务管理器终止进程时,它会调用Win32 TerminateProcess函数,该函数无条件地强制进程(包括其所有拥有的线程)退出。停止执行所有线程/进程,并取消所有挂起的I / O请求。你的计划实际上已经死了。 TerminateProcess函数不会调用CLR提供的关闭序列,因此您的托管应用甚至不知道是否正在关闭。

您建议您在应用程序的进程终止时关注处理对象,但有一些值得指出的事情:

  • 始终努力尽量减少可能造成的伤害。无论何时完成,都要尽早处理对象。不要等到以后。在任何给定的时间,当程序的进程终止时,你应该只保留最小数量的对象,这样可以减少泄漏的可能性。

  • 操作系统通常会在终止时清理并释放大部分这些资源(即句柄等)。

  • 最后,不言而喻,以这种方式终止流程确实是一种特殊情况 - 即使某些资源泄漏,是预期的。您不应该以这种方式关闭应用程序,而不是应该杀死必要的Windows系统进程(即使您在以管理员身份运行时也可以)。

如果这是您关闭控制台应用程序的常规计划,您需要找到另一个计划

答案 1 :(得分:2)

简而言之:你不能!
杀死一个进程正好与一个优雅的退出相反。
如果你正在运行Foreground Threads,发送一个wm_exit不会关闭你的应用程序。由于您有一个控制台应用程序,您可以简单地重定向控制台输入以向您的进程发送“退出”。
此外,我认为您可以将应用程序更改为服务(而不是控制台应用程序),这将为您提供正是你要找的 - >基于Windows内置工具/命令的gracefull退出接口。

相关问题