BackgroundWorker コンポーネントの概要

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

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

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

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

ヒント

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

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

参照

処理手順

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

その他の技術情報

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