【C#】スレッド・バックグラウンドワーカー・backGroundWorker

■ 実装上での必要事項

 * 以下の3つのイベントとキャンセル時の処理を実装する必要がある

 [1] 重い処理を行う『DoWork』イベント・ハンドラ(別スレッドで実行される)
 [2] 進捗状況を表示するための『ProgressChanged』イベント・ハンドラ
 [3] 処理完了時に実行される『RunWorkerCompleted』イベント・ハンドラ
 [4] キャンセル時の処理(CancelAsync()を呼び出す)

■ サンプル

作成手順
【1】デザインでコントロールを追加
【2】プログラムの作成
【3】デザインナー部分の設定

【1】デザインでコントロールを追加

 [1] バックグラウンドワーカーを追加([backgroundWorker]を追加
 [2] プログレスバーを追加(ここでは、[statusStrip]-[toolStripProgressBar]を追加
http://blogs.yahoo.co.jp/dk521123/20513730.html
 [3] 起動用ボタンおよび進捗表示用ラベルを追加(ここでは、それぞれ[button4]、[toolStripProgressBar]を追加

【2】プログラムの作成

#region  バックグラウンドワーカーを実行させるための処理
/// <summary>
///  バックグラウンドワーカーの処理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>時間のかかる処理を行うメソッドを実装する</remarks>
private void button4_Click(object sender, EventArgs e)
{
    this.button4.Enabled = false;
    this.toolStripProgressBar.Enabled = true;

    // バックグランドワーカー起動
    this.backgroundWorker.RunWorkerAsync(100);
}
#endregion

#region  バックグラウンドワーカー処理
/// <summary>
///  バックグラウンドワーカーの処理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>時間のかかる処理を行うメソッドを実装する</remarks>
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    try
    {
        // 待機状態
        Cursor.Current = Cursors.WaitCursor;

        // このメソッドへのパラメータ
        //  この例だと『RunWorkerAsync(100)』なので、
        //  「e.Argument = 100」になる
        int backgroundWorkerArgument = (int)e.Argument;

        // senderの値はbgWorkerの値と同じ
        // BackgroundWorker worker = (BackgroundWorker)sender;

        // 何らかの時間のかかる処理
        for (int i = 0; i < backgroundWorkerArgument; i++)
        {
            // キャンセルされてないか定期的にチェック
            if (this.backgroundWorker.CancellationPending)
            {
                e.Cancel = true;
                return;
            }

            // 擬似的にスリープさせて処理を遅らせている
            System.Threading.Thread.Sleep(100);

            // 進捗率を算出
            int percentage = i * 100 / backgroundWorkerArgument;

            // 算出した進捗率をプログレスバーに反映させるために
            // ProgressChangedイベントを発生させる
            this.backgroundWorker.ReportProgress(percentage);
        }
    }
    catch (Exception)
    {
        // 例外処理
    }
    finally
    {
        // このメソッドからの戻り値
        e.Result = "完了しました";

        // 元に戻す
        Cursor.Current = Cursors.Default;

        // この後、RunWorkerCompletedイベントが発生
    }
}
#endregion

#region  バックグラウンドワーカーの終了処理
/// <summary>
///  バックグラウンドワーカーの終了処理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // 進捗状況をラベルに表示
    this.label1.Text = e.ProgressPercentage + "%実行完了";
    // プログレスバーに進捗率を反映
    this.toolStripProgressBar.Value = e.ProgressPercentage;
}
#endregion

#region  バックグラウンドワーカーの終了処理
/// <summary>
///  バックグラウンドワーカーの終了処理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs 
{
    if (e.Cancelled)
    {
        // キャンセル時は、e.Resultにはアクセスできないので注意

        this.label1.Text = "キャンセルされました";
        MessageBox.Show("キャンセルされました");
    }
    else
    {
        // 処理結果の表示
        this.label1.Text = e.Result.ToString();
        MessageBox.Show("完了");
    }

    // コントロールを元に戻す
    this.toolStripProgressBar.Value = 0;
    this.button4.Enabled = true;
    this.toolStripProgressBar.Enabled = false;
}
#endregion

#region  進行状況表示フォームキャンセル押下処理
/// <summary>
///  進行状況表示フォームキャンセル押下処理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks>
/// ここでは、プログレスバーをクリックすると
/// キャンセルするように実装している
/// </remarks>
private void toolStripProgressBar_Click(object sender, EventArgs e)
{
    // 時間のかかる処理のキャンセル
    this.backgroundWorker.CancelAsync();
}
#endregion

【3】デザインナー部分の設定

[1] バックグラウンドワーカーを追加する
[2] 追加したバックグラウンドワーカーのプロパティ「WorkerReportProgress」、「WorkerSupportCancellation」
    に対して、それぞれ「True」を設定する
[3] 追加したバックグラウンドワーカーのイベント「DoWork」、「ProgressChanged」、「RunWorkerCompeleted」
    に対して、それぞれ「backgroundWorker_DoWork」、「backgroundWorker_ProgressChanged」、
   「backgroundWorker_RunWorkerCompleted」を設定する