私の WinForms アプリは Application.ThreadException イベント ハンドラーをインストールして、すべての未処理の例外を処理します (ハンドラーはダイアログ ボックスを表示します: エラーが発生しました。バグ レポートを送信するには、ここをクリックしてくださいなど)。
問題は、アプリケーションがモーダル ダイアログを表示するときにイベント ハンドラが呼び出されないことです。MessageBox または例外ダイアログを表示すると、すべての例外が黙って飲み込まれます。それらを捕まえる方法はありますか?
以下は、この動作をシミュレートするサンプル WinForms アプリケーションです。このアプリケーションが MessageBox を表示すると、バックグラウンドでスローされたすべての例外が失われます (ThreadException ハンドラーは呼び出されません)。
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
class Program
{
static void Main()
{
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
var form = new MyForm();
Application.ThreadException += (s, e) =>
{
form.AppendText("ThreadException event handler is called.");
MessageBox.Show("Error: " + e.Exception);
};
Application.EnableVisualStyles();
Application.Run(form);
}
}
class MyForm : Form
{
public MyForm()
{
Controls.Add(TextBox = new TextBox
{
Multiline = true,
Dock = DockStyle.Fill
});
ThrowUnhandledException(1);
ThrowUnhandledException(2);
ThrowUnhandledException(3);
}
private async void ThrowUnhandledException(int delaySeconds)
{
await Task.Delay(TimeSpan.FromSeconds(delaySeconds));
AppendText("Throwing a NotImplementedException!");
throw new NotImplementedException();
}
private TextBox TextBox { get; set; }
public void AppendText(string message)
{
TextBox.AppendText(message + Environment.NewLine);
}
}
編集。より明確にするためにコードを更新しました。
例外がスローされると、MyForm は TextBox に次のように書き込みます。
ThreadException ハンドラーが呼び出されると、次のように記述されます。 ThreadException イベント ハンドラーが呼び出されます。メッセージボックスが表示されます。
すべての例外がキャッチされた場合、TextBox には次のように表示されます。
NotImplementedException をスローします。 ThreadException イベント ハンドラが呼び出されます。 NotImplementedException をスローします。 ThreadException イベント ハンドラが呼び出されます。 NotImplementedException をスローします。 ThreadException イベント ハンドラが呼び出されます。
しかし、それは示しています:
NotImplementedException をスローします。 ThreadException イベント ハンドラが呼び出されます。 NotImplementedException をスローします。 NotImplementedException をスローします。