このブログ投稿をご覧ください: AppDomain.ProcessExit は呼び出されることが保証されていません。投稿から引用:
AppDomain.ProcessExit が呼び出される保証はありません。それは非常に回復力があり、信頼性の低い IL から発生する可能性のある一般的な問題 (例外、メモリ不足など) に対処しますが、処理中のイベントが回復できないことがあります (失礼なプロセスのシャットダウンなど)。 .
(...)
コールバックは、プロセス内から呼び出されます。プロセスが乱暴に終了した場合、コールバックは呼び出されません。無作法に終了する一般的な原因には、次のものがあります。
- TaskManager または kernel32!TerminateProcess を介して外部から強制終了されました。
- Stackoverflow ハンドラーがガード ページを超えて消費します。
ProcessExit イベントは、誰かに「あなたがもうすぐ死ぬので電話してください」と伝えるようなものです。死が十分に早く来ると、彼らはメッセージを伝えられないかもしれません.
実際、私はあなたのコードを試してみましたが、1行目または2行目のコメントを外しても「proc exit」を出力しません! (Visual Studio 2013 で、すべての .NET バージョンに対してコンパイルを試みました)。もちろん、例外がスローされず、プロセスが正常に終了した場合は、それを出力します。(編集:リリースモードでコードをコンパイルすると「proc exit」メッセージが表示されますが、デバッグモードでコンパイルすると表示されません)
補足として、コードの推奨リファクタリングを次に示します (完全にはテストされておらず、おそらく不完全ですが、アイデアは得られます)。
static void Main(string[] args)
{
Thread.GetDomain().UnhandledException +=
(sender, eventArgs) => Exiting((Exception)eventArgs.ExceptionObject);
AppDomain.CurrentDomain.ProcessExit +=
(sender, eventArgs) => Exiting(null);
//1 new Thread(_ => { throw new Exception(); }).Start();
//2 ThreadPool.QueueUserWorkItem(_ => { throw new Exception(); });
Thread.Sleep(1000);
return;
}
static void Exiting(Exception exception)
{
//Put common cleanup code here (or at the end of the method)
if(exception == null)
{
Console.WriteLine("normal proc exit");
}
else
{
Console.WriteLine("unhandled exception: " + exception.GetType().Name);
}
}