BackgroundWorker にパラメーターを渡す - C#

BackgroundWorkerへパラメーターや変数を与えるコードを紹介します。

方法1 : RunWorkerAsync メソッドの引数 Argument にパラメーターを与える方法

プログラム1:int型の変数を与える例

UI

下図のUIを作成します。入力用のテキストボックス、出力用の複数行テキストボックス、ボタンを配置します。

コード

下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BackgroundWorkerParameterDemo
{
  public partial class FormParameterInt : Form
  {
    public FormParameterInt()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      int input = Convert.ToInt32(textBox1.Text);
      backgroundWorker1.RunWorkerAsync(input);
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
      int input = (int)e.Argument;
      e.Result = input * input;
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
      int result = (int)e.Result;
      textBox2.Text = "Result:" + Convert.ToString(result);
    }
  }
}

解説

private void button1_Click(object sender, EventArgs e)
{
  int input = Convert.ToInt32(textBox1.Text);
  backgroundWorker1.RunWorkerAsync(input);
}
ボタンのクリックイベントでは、テキストボックスに入力された値を読み取り、数値に変換し変数inputに格納します。BackgroundWorkerのRunWorkerAsyncメソッドの引数に、input変数を与えます。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
  int input = (int)e.Argument;
  e.Result = input * input;
}
RunWorkerAsyncメソッドの呼び出しにより、BackgourndWorkerのDoWorkイベントが発生しバックグラウンド処理が始まります。RunWorkerAsyncメソッドの引数に与えたパラメーターは、DoWorkの引数、DoWorkEventArgsの Argument プロパティに設定されます。今回の例では、int型の変数を与えたため、Argument をintでキャストして与えられたパラメーターを取得します。
パラメータとして受け取った数値を2乗して、結果としてDoWorkEventArgsの Result プロパティに代入して返します。

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  int result = (int)e.Result;
  textBox2.Text = "Result:" + Convert.ToString(result);
}
DoWorkイベントの戻り値は、RunWorkerCompletedイベントのRunWorkerCompletedEventArgs オブジェクトの Resultプロパティに渡されます。渡された結果をテキストボックスに表示します。

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。


上部のテキストボックスに数値を入力します。入力後[button1]をクリックします。


入力した数値を2乗した値がテキストボックスに表示されます。BackgorundWorkerにテキストボックスに入力した値を渡し、BackgroundWorkerでの処理結果をUIスレッドに返し、テキストボックスに表示できている動作が確認できました。

プログラム2:クラスオブジェクトを与える例

RunWorkerAsync の引数にオブジェクトを与えるコード例です。

UI

下図のUIを作成します。入力用のテキストボックスを3つ、出力用の複数行テキストボックスを1つ、ボタンを1つ配置します。

コード

下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BackgroundWorkerParameterDemo
{
  public partial class FormParameterObject : Form
  {
    private class WorkerParams
    {
      public string name;
      public int value1;
      public int value2;
    }

    public FormParameterObject()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      WorkerParams wp = new WorkerParams();
      wp.name = textBox1.Text;
      wp.value1 = Convert.ToInt32(textBox2.Text);
      wp.value2 = Convert.ToInt32(textBox3.Text);

      backgroundWorker1.RunWorkerAsync(wp);
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
      WorkerParams wp = (WorkerParams)e.Argument;
      wp.name = wp.name + ":処理済み";
      wp.value1 = wp.value1 * wp.value2;
      wp.value2 = wp.value2 - wp.value1;

      e.Result = wp;
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
      WorkerParams wp = (WorkerParams)e.Result;

      textBox4.Text += string.Format("{0}\r\nvalue1:{1:d}\r\nvalue2:{2:d}\r\n", wp.name, wp.value1, wp.value2);
    }
  }
}

解説

private void button1_Click(object sender, EventArgs e)
{
  WorkerParams wp = new WorkerParams();
  wp.name = textBox1.Text;
  wp.value1 = Convert.ToInt32(textBox2.Text);
  wp.value2 = Convert.ToInt32(textBox3.Text);

  backgroundWorker1.RunWorkerAsync(wp);
}
ボタンのクリックイベントでは、パラメーターを渡すオブジェクトであるWorkerParams のインスタンスを作成します。続いて、3つのテキストボックスに入力された値を読み取り、WorkerParams クラスのオブジェクトwpに格納します。BackgroundWorkerのRunWorkerAsyncメソッドの引数に、wpを与えます。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
  WorkerParams wp = (WorkerParams)e.Argument;
  wp.name = wp.name + ":処理済み";
  wp.value1 = wp.value1 * wp.value2;
  wp.value2 = wp.value2 - wp.value1;

  e.Result = wp;
}
RunWorkerAsyncメソッドの呼び出しにより、BackgourndWorkerのDoWorkイベントが発生しバックグラウンド処理が始まります。RunWorkerAsyncメソッドの引数に与えたパラメーターは、DoWorkの引数、DoWorkEventArgsの Argument プロパティに設定されます。今回の例では、int型の変数を与えたため、Argument をintでキャストして与えられたパラメーターを取得します。
パラメータとして受け取った数値を2乗して、結果としてDoWorkEventArgsの Result プロパティに代入して返します。

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  int result = (int)e.Result;
  textBox2.Text = "Result:" + Convert.ToString(result);
}
DoWorkイベントの戻り値は、RunWorkerCompletedイベントのRunWorkerCompletedEventArgs オブジェクトの Resultプロパティに渡されます。渡された結果をテキストボックスに表示します。

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。


上部のテキストボックスに値を入力します。入力後[button1]をクリックします。


入力した値を処理した結果がテキストボックスに表示されます。BackgorundWorkerにテキストボックスに入力した値を渡し、BackgroundWorkerでの処理結果をUIスレッドに返し、テキストボックスに表示できている動作が確認できました。

方法2 : クラスのメンバ変数を利用する方法

UI

下図のUIを作成します。

コード

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BackgroundWorkerParameterDemo
{
  public partial class FormParameterObjectMemberValue : Form
  {
    private WorkerParams sparam;

    private class WorkerParams
    {
      public string name;
      public int value1;
      public int value2;
    }

    public FormParameterObjectMemberValue()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      WorkerParams wp = new WorkerParams();
      wp.name = textBox1.Text;
      wp.value1 = Convert.ToInt32(textBox2.Text);
      wp.value2 = Convert.ToInt32(textBox3.Text);
      sparam = wp;

      backgroundWorker1.RunWorkerAsync();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
      sparam.name = sparam.name + ":処理済み";
      sparam.value1 = sparam.value1 * sparam.value2;
      sparam.value2 = sparam.value2 - sparam.value1;
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
      textBox4.Text += string.Format("{0}\r\nvalue1:{1:d}\r\nvalue2:{2:d}\r\n", sparam.name, sparam.value1, sparam.value2);
    }
  }
}

解説

先のRunWorkerAsync の引数にオブジェクトを与えるプログラムと同様にWorkerParamsクラスをBackgroundWorkerに情報を渡すクラスとします。WorkerParamsクラス型の変数 sparam をフォームのメンバ変数として定義し、この変数をフォームとBackgroundWorkerから参照することで、BackgroundWorkerへの情報の受け渡しをします。
[Button1]をクリックしたタイミングで、WorkerParamsクラスのインスタンスを作成し、テキストボックスの値を読み取り、WorkerParamsのオブジェクトのメンバ変数に値を設定します。値の設定後 sparam 変数にWorkerParamsのオブジェクトを代入します。
sparamの設定後、backgroundWorker1.RunWorkerAsync();メソッドを呼び出し、BackgroundWorkerの処理を開始します。BackgroundWorkerの処理イベントのDoWorkでは、sparam 変数を参照し、UIスレッドから渡された値を利用して処理を実行します。BackgroundWorkerの処理完了イベントのRunWorkerCompletedでも同様に、sparam 変数を参照しBackgroundWorkerのスレッドで処理された値を参照してテキストボックスに表示します。

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。


テキストボックスに値を入力します。値が入力できたら[Button1]を繰りくします。


画面下部のテキストボックスに処理後の値が表示されます。Nameの値には":処理済み"が末尾に追加されます。value1には入力した数値をかけ合わせた値が、value2には、2つ目の数値から、入力した数値をかけ合わせた値を引いた値が表示されます。

著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2017-10-07
作成日: 2017-01-13
iPentec all rights reserverd.