この質問を調査した結果: Rethrowing exception in Task doesn't make the Task to go to faulted state、理解できない非常に奇妙な動作に気付きましたThreadAbortException。
今、私はそれThreadAbortExceptionが非常に特別な種類の例外であることを知っています. そして、それが言うとき、ドキュメントはそれについてかなり明確です:
ThreadAbortExceptionキャッチできる特別な例外ですが、catchブロックの最後で自動的に再び発生します。
シナリオ #1 : 文書化された動作。
static void Main(string[] args)
{
try
{
Thread.CurrentThread.Abort();
}
catch (Exception tae)
{
Console.WriteLine("caught exception: " + tae.GetType().Name);
}
Console.WriteLine("will never be reached");
}
予想どおり、ThreadAbortExceptionは自動的に再スローされ、次の出力が得られます。
caught exception: ThreadAbortException
シナリオ #2 : 興味深いのは、catchブロックで別の例外をスローすることにしたときです。
static void Main(string[] args)
{
try
{
Thread.CurrentThread.Abort();
}
catch (Exception tae)
{
Console.WriteLine("caught exception: " + tae.GetType().Name);
throw new ApplicationException(); // will ThreadAbortException take precedence?
}
Console.WriteLine("will never be reached");
}
この場合、 がスローされたにもかかわらず、文書化された動作が確実に保持されるようにApplicationException、が再スローされると想定しました。ThreadAbortException驚いたことに、これが結果の出力です。
caught exception: ThreadAbortException
Unhandled Exception: System.ApplicationException: Error in the application.
at ConsoleApplication1.Program.Main(String[] args) in C:\projects\ConsoleApplication1\Program.cs:line 193
はApplicationException実際に交換して、投げられるのを防ぎThreadAbortExceptionましたか?!?
シナリオ #3 : 最後に、さらに興味深いことに、既存の例外処理をもう 1 つのtry-catchレイヤーでラップします。
static void Main(string[] args)
{
try
{
try
{
Thread.CurrentThread.Abort();
}
catch (Exception tae)
{
Console.WriteLine("caught exception: " + tae.GetType().Name);
throw new ApplicationException();
}
}
catch (Exception outerEx)
{
Console.WriteLine("caught outer exception: " + outerEx.GetType().Name);
}
Console.WriteLine("will never be reached");
}
今、私は何を期待すべきかよくわかりません。外側のcatchブロックでキャッチされるのはどの例外ですか? でしょうApplicationExceptionか?もしそうなら、それは私が例外を飲み込み、実際にwill never be reached文字列を出力することができるということですか?
これは実際の出力です:
caught exception: ThreadAbortException
caught outer exception: ApplicationException
catch上記の出力から、外側のブロックが実際に をキャッチしているように見えますApplicationException。しかし、その catchブロックの終わりまでにThreadAbortException、突然、何もないところから再び現れて、再び投げ出されますか?
質問: 誰かがシナリオ #2 と #3 を説明し、調整してもらえますか? シナリオ 2 でThreadAbortException、予期せず別の例外に置き換えられたように見えるのはなぜですか? ThreadAbortExceptionしかし、シナリオ #3 では、ずっとそこにいたように見えますか? これはどのように起こっていますか?この動作はどこかに文書化されていますか?