如何检测应用程序何时终止?

这是我最初的问题的后续工作,我想提出我的发现,并要求更正,想法和见解。 我的发现(或者说是解释)来自于人们对我以前的问题的回答,阅读MSDN .NET 3.5文档和debugging.NET 3.5代码。 我希望这对那些想知道如何检测应用程序何时终止的人有价值。

事件:

  • System.AppDomain.CurrentDomain.ProcessExit :当进程退出时引发,例如,在默认的AppDomain和其他所有东西都被卸载之后[总执行时间被限制在3秒内]。 对于WPF,请改用System.Windows.Application.Exit 。 对于Windows窗体,在main方法中的Application.Run(...)之后运行代码。

  • System.AppDomain.CurrentDomain.DomainUnload :在默认AppDomain以外的AppDomain卸载时引发,例如,在运行具有unit testing框架的类(带有TestDriven.NET的MbUnit)时引发。

  • System.AppDomain.CurrentDomain.UnhandledException :(如果在默认的AppDomain处理:)在任何线程中引发任何未处理的exception,无论该线程启动了什么AppDomain 。这意味着,这可以用作所有未处理的exception。

  • System.Windows.Application.Exit :当WPF应用程序(即默认AppDomain )正常退出时引发。 重写System.Windows.Application.OnExit来利用它。

  • Finalizer(C#中的析构函数):当垃圾回收器释放非托pipe资源时运行。 [总执行时间有限!

活动顺序:

WPF应用程序:优雅退出

  1. System.Windows.Application.Exit
  2. System.AppDomain.CurrentDomain.ProcessExit
  3. 终结

WPF应用程序:未处理的exception

  1. System.AppDomain.CurrentDomain.UnhandledException

在TestDriven.NET中运行的MbUnit:通过testing(优雅退出)

  1. System.AppDomain.CurrentDomain.DomainUnload
  2. 终结

在TestDriven.NET中运行的MbUnit:失败的testing(未处理的exception由MbUnit处理)

  1. AppDomain.CurrentDomain.DomainUnload
  2. 终结

问题:

  • 我的解释/发现是否正确?
  • 你知道我所遗漏的更多细节吗? 例如,终结器的总执行时间是多less?
  • 你知道我知道的其他事件吗?
  • 那里有什么事件,他们在其他应用程序,如Windows窗体,Web服务,ASP.NET网站等提出什么顺序?

由ssg31415926的问题/答案提示(这个问题有点反转),还有Application.SessionEnding ,当用户注销或closures时调用。 它在Exit事件之前调用。

调用Dispatcher.BeginInvokeShutdown() ,不会调用Application.Exit

  1. 终结器执行的默认超时是2秒。

你写:

System.AppDomain.CurrentDomain.UnhandledException:(如果在默认的AppDomain中处理:)在任何线程中引发任何未处理的exception,无论该线程启动了什么AppDomain。这意味着,这可以用作所有未处理的exception。

我不认为这是正确的。 试试下面的代码:

 using System; using System.Threading; using System.Threading.Tasks; namespace AppDomainTestingUnhandledException { class Program { static void Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += (sender, eventArgs) => Console.WriteLine("Something went wrong! " + args); var ad = AppDomain.CreateDomain("Test"); var service = (RunInAnotherDomain) ad.CreateInstanceAndUnwrap( typeof(RunInAnotherDomain).Assembly.FullName, typeof(RunInAnotherDomain).FullName); try { service.Start(); } catch (Exception e) { Console.WriteLine("Crash: " + e.Message); } finally { AppDomain.Unload(ad); } } } class RunInAnotherDomain : MarshalByRefObject { public void Start() { Task.Run( () => { Thread.Sleep(1000); Console.WriteLine("Uh oh!"); throw new Exception("Oh no!"); }); while (true) { Console.WriteLine("Still running!"); Thread.Sleep(300); } } } } 

据我所知,UnhandledException处理程序永远不会被调用,并且线程将会静静地崩溃(或者如果您在debugging器中运行它,就会唠叨你)。

只需在主窗体上添加一个新事件即可:

 private void frmMain_Load(object sender, EventArgs e) { Application.ApplicationExit += new EventHandler(this.WhenItStopsDoThis); } private void WhenItStopsDoThis(object sender, EventArgs e) { //Program ended. Do something here. }