如何检测应用程序何时终止?
这是我最初的问题的后续工作,我想提出我的发现,并要求更正,想法和见解。 我的发现(或者说是解释)来自于人们对我以前的问题的回答,阅读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应用程序:优雅退出
-
System.Windows.Application.Exit
-
System.AppDomain.CurrentDomain.ProcessExit
- 终结
WPF应用程序:未处理的exception
-
System.AppDomain.CurrentDomain.UnhandledException
在TestDriven.NET中运行的MbUnit:通过testing(优雅退出)
-
System.AppDomain.CurrentDomain.DomainUnload
- 终结
在TestDriven.NET中运行的MbUnit:失败的testing(未处理的exception由MbUnit处理)
-
AppDomain.CurrentDomain.DomainUnload
- 终结
问题:
- 我的解释/发现是否正确?
- 你知道我所遗漏的更多细节吗? 例如,终结器的总执行时间是多less?
- 你知道我知道的其他事件吗?
- 那里有什么事件,他们在其他应用程序,如Windows窗体,Web服务,ASP.NET网站等提出什么顺序?
由ssg31415926的问题/答案提示(这个问题有点反转),还有Application.SessionEnding ,当用户注销或closures时调用。 它在Exit事件之前调用。
调用Dispatcher.BeginInvokeShutdown()
,不会调用Application.Exit
。
- 终结器执行的默认超时是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. }