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");
    }
}