これは私の 最初の質問 のフォローアップであり、私の発見を提示し、修正、アイデア、洞察を求めたいと思います。私の調査結果(またはむしろ解釈)は、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
がアンロードされると発生します。ユニットテストフレームワーク(TestDriven.NETを備えたMbUnit)でクラスを実行する場合。
_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
_質問:
Ssg31415926の質問/回答(この質問は少し逆です)によって促されます Application.SessionEnding もあります。これは、ユーザーがログオフまたはシャットダウンしたときに呼び出されます。 Exitイベントの前に呼び出されます。
Dispatcher.BeginInvokeShutdown()
が呼び出されると、Application.Exit
は呼び出されません。
あなたが書く:
System.AppDomain.CurrentDomain.UnhandledException:(デフォルトのAppDomain:で処理された場合)スレッドがどのAppDomainで開始されたかに関係なく、スレッド内の未処理の例外に対して発生します。つまり、これはすべての未処理の例外のキャッチオールとして使用できます。 。
これは正しいとは思いません。次のコードを試してください:
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ハンドラーは呼び出されず、スレッドは静かにクラッシュします(または、デバッガーで実行した場合は問題が発生します)。
メインフォームに新しいイベントを追加するだけです。
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.
}