BackgroundWorker
C# 2.0 から導入された BackgroundWorker で発生した例外をキャッチするためのメモ
以下のようなコードの場合、bw_DoWork で発生した例外は完全に無視されて「completed」と表示されたメッセージボックスが表示される。
namespace WindowsApplication4 { public partial class Form1 : Form { public Form1() { InitializeComponent(); backgroundWorker1.DoWork += new DoWorkEventHandler(bw_DoWork); backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); } void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { MessageBox.Show(this, "completed"); } void bw_DoWork(object sender, DoWorkEventArgs e) { throw new Exception("The method or operation is not implemented."); } private void button1_Click(object sender, EventArgs e) { backgroundWorker1.RunWorkerAsync(); } } }
これを避けるためには RunWorkerCompleted イベントハンドラで RunWorkerCompletedEventArgs.Error プロパティをチェックして、NULL でなければスローするようにすればいい。RunWorkerCompleted イベントハンドラは UI スレッドで実行されるので、以下のように書いておけば例外はキャッチできる。
static class Program { [STAThread] static void Main() { Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(app_ThreadException); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } static void app_ThreadException(object sender, ThreadExceptionEventArgs e) { MessageBox.Show(null, e.Exception.Message, "catch@ThreadException"); } }