这是对我initial question的跟进,我想提出我的发现,并要求更正,想法和见解。我的发现(或者更确切地说是解释)来自人们对我之前的问题的回答,阅读MSDN .NET 3.5文档和调试.NET 3.5代码。我希望这对那些想知道如何检测应用程序何时终止的人有价值。
活动:
System.AppDomain.CurrentDomain.ProcessExit
:在流程退出时引发,例如在默认AppDomain
之后,其他所有内容都被卸载[总执行时间仅限于3秒!]。对于WPF,请改用System.Windows.Application.Exit
。对于Windows窗体,请在main方法中Application.Run(...)
之后运行代码。
System.AppDomain.CurrentDomain.DomainUnload
:在默认AppDomain
以外的AppDomain
卸载时引发,例如当使用单元测试框架运行类时(MbUnit和TestDriven.NET)。
System.AppDomain.CurrentDomain.UnhandledException
:(如果在默认AppDomain
处理:)为任何线程中的任何未处理的异常引发,无论线程是从哪个AppDomain
开始。这意味着,这可以用作所有未处理异常的全部内容。
System.Windows.Application.Exit
:当WPF应用程序(即默认AppDomain
)正常退出时引发。覆盖System.Windows.Application.OnExit
以利用它。
终结器(C#中的析构函数):当垃圾收集器释放非托管资源时运行。 [总执行时间有限!]。
活动顺序:
WPF应用程序:优雅退出
System.Windows.Application.Exit
System.AppDomain.CurrentDomain.ProcessExit
WPF应用程序:未处理的异常
System.AppDomain.CurrentDomain.UnhandledException
在TestDriven.NET中运行的MbUnit:通过测试(优雅退出)
System.AppDomain.CurrentDomain.DomainUnload
在TestDriven.NET中运行的MbUnit:测试失败(未处理的异常由MbUnit处理)
AppDomain.CurrentDomain.DomainUnload
问题:
答案 0 :(得分:7)
由ssg31415926的问题/答案提示(这个问题有点颠倒),还有Application.SessionEnding在用户注销或关闭时调用。它在Exit事件之前调用。
答案 1 :(得分:2)
调用Dispatcher.BeginInvokeShutdown()
时,将不会调用Application.Exit
。
答案 2 :(得分:1)
答案 3 :(得分:1)
你写道:
System.AppDomain.CurrentDomain.UnhandledException :(如果在默认的AppDomain中处理:)为任何线程中的任何未处理的异常引发,无论线程启动的是什么AppDomain。这意味着,这可以用作catch-all for所有未处理的例外。
我不认为这是正确的。请尝试以下代码:
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处理程序,并且线程将以静默方式崩溃(或者如果在调试器中运行它,则唠叨你)。
答案 4 :(得分:0)
只需在主表单上添加新活动:
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.
}