BackgroundWorker コンポーネントの概要

更新 : 2007 年 11 月

一般的な操作には、実行時間が長くかかるものが数多くあります。たとえば、次のような操作です。

  • イメージのダウンロード

  • Web サービスの起動

  • ファイルのダウンロードとアップロード (ピアツーピア アプリケーションの場合を含む)

  • ローカルでの複雑な計算

  • データベース トランザクション

  • ローカル ディスク アクセス (前提としてメモリ アクセスに比べて低速です)

以上のような操作の実行時には、ユーザー インターフェイスがハングアップすることがあります。応答性に優れたインターフェイスを必要としながらも、このような操作との関連で長時間の遅延に直面する場合は、BackgroundWorker コンポーネントが便利なソリューションになります。

BackgroundWorker コンポーネントを使用すると、時間のかかる操作を、アプリケーションのメイン UI スレッドとは別のスレッドで非同期的に ("バックグラウンドで") 実行できます。BackgroundWorker を使用するには、バックグラウンドで実行する、時間のかかるワーカー メソッドをこのコンポーネントに通知して、RunWorkerAsync メソッドを呼び出すだけです。呼び出し元スレッドが正常に動作し続けると共に、ワーカー メソッドも非同期的に動作します。このメソッドが終了すると、BackgroundWorker は、RunWorkerCompleted イベントを起動して、呼び出し元スレッドに警告します。このイベントには、オプションで操作の結果を含めることもできます。

BackgroundWorker コンポーネントは、[コンポーネント] タブの [ツールボックス] で選択できます。BackgroundWorker をフォームに追加するには、BackgroundWorker コンポーネントをフォームにドラッグします。このコンポーネントはコンポーネント トレイに表示され、プロパティが [プロパティ] ウィンドウに表示されます。

非同期操作を開始するには、RunWorkerAsync メソッドを使用します。RunWorkerAsync は、オプションの object パラメータを受け取り、このパラメータを使用してワーカー メソッドに引数を渡すことができます。BackgroundWorker クラスは、DoWork イベントを公開します。このイベントには、DoWork イベント ハンドラ経由でワーカー スレッドをアタッチします。

DoWork イベント ハンドラは、Argument プロパティを持つ DoWorkEventArgs パラメータを受け取ります。このプロパティは、RunWorkerAsync からパラメータを受け取り、DoWork イベント ハンドラで呼び出されるワーカー メソッドに渡されます。次の例は、ComputeFibonacci というワーカー メソッドの結果を代入する方法を示しています。これは、「方法 : バックグラウンド操作を使用するフォームを実装する」に記載されている例の一部です。

' This event handler is where the actual work is done.
Private Sub backgroundWorker1_DoWork( _
ByVal sender As Object, _
ByVal e As DoWorkEventArgs) _
Handles backgroundWorker1.DoWork

    ' Get the BackgroundWorker object that raised this event.
    Dim worker As BackgroundWorker = _
        CType(sender, BackgroundWorker)

    ' Assign the result of the computation
    ' to the Result property of the DoWorkEventArgs
    ' object. This is will be available to the 
    ' RunWorkerCompleted eventhandler.
    e.Result = ComputeFibonacci(e.Argument, worker, e)
End Sub 'backgroundWorker1_DoWork
// This event handler is where the actual,
// potentially time-consuming work is done.
private void backgroundWorker1_DoWork(object sender, 
    DoWorkEventArgs e)
{   
    // Get the BackgroundWorker that raised this event.
    BackgroundWorker worker = sender as BackgroundWorker;

    // Assign the result of the computation
    // to the Result property of the DoWorkEventArgs
    // object. This is will be available to the 
    // RunWorkerCompleted eventhandler.
    e.Result = ComputeFibonacci((int)e.Argument, worker, e);
}
// This event handler is where the actual,
// potentially time-consuming work is done.
void backgroundWorker1_DoWork( Object^ sender, DoWorkEventArgs^ e )
{
   // Get the BackgroundWorker that raised this event.
   BackgroundWorker^ worker = dynamic_cast<BackgroundWorker^>(sender);

   // Assign the result of the computation
   // to the Result property of the DoWorkEventArgs
   // object. This is will be available to the 
   // RunWorkerCompleted eventhandler.
   e->Result = ComputeFibonacci( safe_cast<Int32>(e->Argument), worker, e );
}
// This event handler is where the actual,
// potentially time-consuming work is done.
private void backgroundWorker1_DoWork(Object sender, DoWorkEventArgs e)
{
    // Get the BackgroundWorker that raised this event.
    BackgroundWorker worker = (BackgroundWorker)sender;

    // Assign the result of the computation
    // to the Result property of the DoWorkEventArgs
    // object. This is will be available to the 
    // RunWorkerCompleted eventhandler.
    e.set_Result(new Long(ComputeFibonacci(System.Convert.ToInt32
        (e.get_Argument()), worker, e)));
    //e.Result = ComputeFibonacci((int)e.Argument, worker, e); 
} //backgroundWorker1_DoWork

イベント ハンドラの使い方の詳細については、「イベントとデリゲート」を参照してください。

8xs8549b.alert_caution(ja-jp,VS.90).gif注意 :

どのような種類のマルチスレッドを使用している場合でも、非常に深刻で複雑なバグを引き起こしてしまう可能性があります。マルチスレッドを使用するソリューションを実装する前に、「マネージ スレッド処理の実施」を参照してください。

BackgroundWorker クラスの使い方の詳細については、「方法 : バックグラウンドで操作を実行する」を参照してください。

参照

処理手順

方法 : バックグラウンド操作を使用するフォームを実装する

その他の技術情報

Visual Basic におけるマルチスレッド