最近知りました。
詳細については、以下を参考ください。
https://github.com/dotnet/runtime/issues/67214
本件ですが、
- WINDOWSは問題なし
- MACはダメ
- LINUXはダメ
ということのようで、LINUXでやってみました。
環境は以下の通りです。
$ cat /etc/os-release NAME="Pop!_OS" VERSION="22.04 LTS" $ dotnet --version 6.0.402 |
(1. 同期のダメな場合)
public class Program { public static void Main(string[] args) { try { Console.WriteLine("main"); throw new Exception(); } catch (Exception e) { Console.WriteLine("error"); throw; // ←こいつが原因 } finally { Console.WriteLine("finally"); // ここを通過しない } } } |
(2. 同期でOKな場合)
public class Program { public static void Main(string[] args) { try { try { Console.WriteLine("main"); throw new Exception(); } catch (Exception e) { Console.WriteLine("error"); throw; // ←こいつがいてもfinallyに入る } finally { Console.WriteLine("finally"); // 上位のエラーハンドラーがいればOK } } catch (Exception e) { Console.WriteLine("error - wrapper"); } } } |
(3. 非同期の場合)
public class Program { public static async Task Main(string[] args) { try { Console.WriteLine("main"); throw new Exception(); } catch (Exception e) { Console.WriteLine("error"); throw; // ←こいつがいてもfinallyに入る } finally { Console.WriteLine("finally"); // async修飾子があればOK } } } |
(4. NET6からの簡易構文の場合)
try { Console.WriteLine("main"); throw new Exception(); } catch (Exception e) { Console.WriteLine("error"); throw; // ←こいつがいるとダメ } finally { Console.WriteLine("finally"); // ここを通過しない } |
以上のように、4つのパターンで試してみました。
asyncの場合は何も気にする必要はないですが、他パターンでは一考が必要かなと。
ちなみに以下のようなエラーになります。
Unhandled exception. System.Exception: Exception of type 'System.Exception' was thrown. |
これって、コンテナでやるときにやばいかなと思う。。
気をつけてください。
また、シャットダウンハンドラー(以下のようなコード)を仕込んでみましたが、
動いたのは、「2. 同期でOKな場合」だけでした。
そもそも、asyncはシャットダウンハンドラーって使えない?(要調査)
AppDomain.CurrentDomain.ProcessExit += new EventHandler(ShutdownHander); public static void ShutdownHander(object sender, EventArgs e) { Console.WriteLine("shutdown"); } |
(追記)
Unhandled exceptionは、ProcessExitには反応しないようです。
こちらを使う必要があります。
https://learn.microsoft.com/ja-jp/dotnet/api/system.appdomain.unhandledexception?view=net-8.0
以上
コメントがあればどうぞ