Rob*_*ker 5 events console-application exit exit-handler .net-2.0
当应用程序退出时,需要通知我们的代码库.所以我们订阅了System.Window.Forms.Application.ApplicationExit事件.这适用于Winforms应用程序,但它是否也适用于其他类型的应用程序,如控制台应用程序,服务和Web应用程序(如ASP.NET)?命名空间会表明它没有,并且可能在Application.Exit()被调用时(明确地或隐含地)被提升,这可能不适合调用这些其他情况.
还有一些其他事件在这些其他情况下会更好,或者更普遍吗(如果它适用于Winforms也很好)?例如,是否有一个关于何时Environment.Exit()被调用的事件(控制台应用程序)?
我在System.Diagnostic.Process中发现了一个Exited事件,但这似乎是为了监视另一个进程的退出,并且它似乎没有被进程接收到它自己(例如,Process.GetCurrentProcess().Exited += Process_Exited; Process.GetCurrentProcess().EnableRaisingEvents = true;).我认为它可能只是在该过程实际退出后才会提出,所以这不起作用.
这尤其适用于.NET 2.0和C#.
Rob*_*ker 10
我们终于找到了更多关于此的信息(但是到那时我的机器已经重建并且在这里丢失了我未注册的配置文件的cookie;希望它会让我遇到这个答案).
进一步的调查最终发现了一些我们发现有用的事件:
System.Windows.Forms.Application.ThreadExit- 当消息循环退出时
System.Windows.Forms.Application.ApplicationExit触发 - 当所有消息循环退出时
System.AppDomain.CurrentDomain.DomainUnload触发 - 当默认退出以外的
System.AppDomain.CurrentDomain.ProcessExit域退出时触发 - 当默认应用程序域退出时
System.AppDomain.CurrentDomain.UnhandledException触发 - 当未捕获的异常发生时触发,结束应用程序.
对于给定的应用程序域,只有一个DomainUnload或多个ProcessExit事件是可能的,具体取决于它是进程的默认(顶级)域还是创建为子域(例如,在Web服务器上).如果应用程序不知道它可能是什么(如我们的情况),它需要订阅两者,如果它想要捕获自己的实际卸载.此外,似乎UnhandledException(从.NET2.0开始总是致命的)可能会阻止其他两个事件,因此可能是第三种情况需要处理.这三个事件应该适用于任何.NET应用程序.
有一点需要注意,执行时间ProcessExit是有限的(大约4秒?),因此可能无法在该事件处理程序中进行大量的"最终"工作.它需要是可以快速完成的事情.
这些Application事件仅适用于WinForms应用程序(我们怀疑它们可能不适用于纯WPF应用程序).命名可能会产生误导,因为它们是以最基本的正常使用命名的,具有某些假设. ThreadExit与UI线程的实际System.Threading.Thread而非与消息循环(Application.Run())相关,并且ApplicationExit类似地涉及一个或多个UI线程上的应用程序表单的集合.通常,一旦调用Application.Run()返回,从线程的入口方法调用,则入口方法快速结束,然后线程本身结束.一旦所有UI线程退出,WinForms应用程序通常都会完成并退出.
另一个值得注意的System.Windows.Forms.Application.ThreadException事件是事件.可以配置Windows消息循环以捕获在处理消息时发生的异常并发送此事件,而不是让它们成为未被捕获(并因此致命)的异常.捕获这些异常允许消息循环(以及该UI线程)继续运行(在中止当前消息处理程序之后).对于给定的线程(订阅覆盖任何以前的订阅者),此事件只能有一个订阅者,并且必须在创建和订阅任何Form之前配置它,然后才能进入消息循环.有关此事件System.Windows.Forms.Applicaton.SetUnhandledExceptionMode()的详细信息,请参阅MSDN帮助.