■No66332 (ほくと さん) に返信
> ★の一行がなければ、予想通り、Form1側でキャッチすることができるのですが、
それはあくまでデバッグ実行時だけです。
「デバッグなしで実行」や exe を直接起動すると、.NET の例外ダイアログが表示されることでしょう。
> ★の1行があれば、Form1でキャッチすることはできずに、「Application_ThreadException」に流れ込んでしまいます。
そういう仕様(設計)です。
ShowDialog の中ではメッセージループが回ります。
ShowDialog および Application.Run の中で実行されるメッセージループは、以下のような構造をとっています。
// 何らかのイベント発生
try
{
// イベントの処理を実行
}
catch(Exception ex)
{
if (/* ThreadException が設定されているか */)
{
// ThreadException を実行
}else{
// デバッグ時はデバッグハンドラに渡す
// デバッグなし時は独自の例外ダイアログを表示する
}
}
デバッグハンドラ周りの動きをきちんと追いかけていませんが、振る舞いから察するに、外に例外を throw するのでしょうね。
従って、ShowDialog の外の try-catch に反応します。
が、これはあくまでデバッグ時の挙動なので、この挙動に頼った設計・実装は NG です。
この挙動を変える方法として、Application.SetUnhandledExceptionMode があります。
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.application.setunhandledexceptionmode.aspx
ThrowException にすると ShowDialog の外で catch できるようになりますが、ThreadException イベントは機能しなくなりますし、
ちょっとした例外でもダイアログが閉じてしまう、アプリが不正終了で例外のダイアログが出なくなってしまうといった振る舞いになることを
受容する必要があります。
ThreadException イベントを使いつつ、ShowDialog の外で catch してこっちに来るものはイベントに渡したくないというのは両立しないので、
大方針を見直してください。
(ShowDialog の外で catch するのをあきらめる or ThreadException を使うのをあきらめる)