次の方法で共有


チュートリアル : 操作をバックグラウンドで実行する

完了するまでに時間がかかる操作があり、ユーザー インターフェイスが遅くならないようにする場合は、BackgroundWorker クラスを使用して別のスレッドで操作を実行できます。

ここで使用するコード例の完全なリストについては、「方法 : バックグラウンドで操作を実行する」を参照してください。

注意

実際に画面に表示されるダイアログ ボックスとメニュー コマンドは、アクティブな設定またはエディションによっては、ヘルプの説明と異なる場合があります。 設定を変更するには、[ツール] メニューの [設定のインポートとエクスポート] をクリックします。 詳細については、「設定の操作」を参照してください。

操作をバックグラウンドで実行するには

  1. Windows フォーム デザイナーでフォームをアクティブにした状態で、ツールボックスから 2 つの Button コントロールをフォームにドラッグし、ボタンの Name プロパティおよび Text プロパティを以下の表のとおりに設定します。

    Button

    名前

    テキスト

    button1

    startBtn

    Start

    button2

    cancelBtn

    Cancel

  2. ツールボックスを開き、[コンポーネント] タブをクリックします。次に、BackgroundWorker コンポーネントをフォームにドラッグします。

    backgroundWorker1 コンポーネントが、コンポーネント トレイに表示されます。

  3. [プロパティ] ウィンドウで、WorkerSupportsCancellation プロパティを true に設定します。

  4. [プロパティ] ウィンドウの [イベント] ボタンをクリックし、DoWork イベントおよび RunWorkerCompleted イベントをダブルクリックしてイベント ハンドラーを作成します。

  5. 完了するまでに時間のかかるコードを DoWork イベント ハンドラーに挿入します。

  6. 操作に必要なパラメーターを DoWorkEventArgs パラメーターの Argument プロパティから抽出します。

  7. 計算の結果を DoWorkEventArgsResult プロパティに代入します。

    この値は、RunWorkerCompleted イベント ハンドラーで使用できます。

    Private Sub backgroundWorker1_DoWork( _
    sender As Object, e As DoWorkEventArgs) _
    Handles backgroundWorker1.DoWork
    
       ' Do not access the form's BackgroundWorker reference directly.
       ' Instead, use the reference provided by the sender parameter.
       Dim bw As BackgroundWorker = CType( sender, BackgroundWorker )
    
       ' Extract the argument.
       Dim arg As Integer = Fix(e.Argument)
    
       ' Start the time-consuming operation.
       e.Result = TimeConsumingOperation(bw, arg)
    
       ' If the operation was canceled by the user, 
       ' set the DoWorkEventArgs.Cancel property to true.
       If bw.CancellationPending Then
          e.Cancel = True
       End If
    
    End Sub   
    
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        // Do not access the form's BackgroundWorker reference directly.
        // Instead, use the reference provided by the sender parameter.
        BackgroundWorker bw = sender as BackgroundWorker;
    
        // Extract the argument.
        int arg = (int)e.Argument;
    
        // Start the time-consuming operation.
        e.Result = TimeConsumingOperation(bw, arg);
    
        // If the operation was canceled by the user, 
        // set the DoWorkEventArgs.Cancel property to true.
        if (bw.CancellationPending)
        {
            e.Cancel = true;
        }
    }
    
  8. 操作の結果を取得するコードを RunWorkerCompleted イベント ハンドラーに挿入します。

    ' This event handler demonstrates how to interpret 
    ' the outcome of the asynchronous operation implemented
    ' in the DoWork event handler.
    Private Sub backgroundWorker1_RunWorkerCompleted( _
    sender As Object, e As RunWorkerCompletedEventArgs) _
    Handles backgroundWorker1.RunWorkerCompleted
    
       If e.Cancelled Then
          ' The user canceled the operation.
          MessageBox.Show("Operation was canceled")
       ElseIf (e.Error IsNot Nothing) Then
          ' There was an error during the operation.
          Dim msg As String = String.Format("An error occurred: {0}", e.Error.Message)
          MessageBox.Show(msg)
       Else
          ' The operation completed normally.
          Dim msg As String = String.Format("Result = {0}", e.Result)
          MessageBox.Show(msg)
       End If
    End Sub   
    
    // This event handler demonstrates how to interpret 
    // the outcome of the asynchronous operation implemented
    // in the DoWork event handler.
    private void backgroundWorker1_RunWorkerCompleted(
        object sender, 
        RunWorkerCompletedEventArgs e)
    {   
        if (e.Cancelled)
        {
            // The user canceled the operation.
            MessageBox.Show("Operation was canceled");
        }
        else if (e.Error != null)
        {
            // There was an error during the operation.
            string msg = String.Format("An error occurred: {0}", e.Error.Message);
            MessageBox.Show(msg);
        }
        else
        {
            // The operation completed normally.
            string msg = String.Format("Result = {0}", e.Result);
            MessageBox.Show(msg);
        }
    }
    
  9. TimeConsumingOperation メソッドを実装します。

    ' This method models an operation that may take a long time 
    ' to run. It can be cancelled, it can raise an exception,
    ' or it can exit normally and return a result. These outcomes
    ' are chosen randomly.
    Private Function TimeConsumingOperation( _
    bw As BackgroundWorker, _
    sleepPeriod As Integer) As Integer
    
       Dim result As Integer = 0
    
       Dim rand As New Random()
    
         While Not bw.CancellationPending
             Dim [exit] As Boolean = False
    
             Select Case rand.Next(3)
                 ' Raise an exception.
                 Case 0
                     Throw New Exception("An error condition occurred.")
                     Exit While
    
                     ' Sleep for the number of milliseconds
                     ' specified by the sleepPeriod parameter.
                 Case 1
                     Thread.Sleep(sleepPeriod)
                     Exit While
    
                     ' Exit and return normally.
                 Case 2
                     result = 23
                     [exit] = True
                     Exit While
    
                 Case Else
                     Exit While
             End Select
    
             If [exit] Then
                 Exit While
             End If
         End While
    
       Return result
    End Function
    
    // This method models an operation that may take a long time 
    // to run. It can be cancelled, it can raise an exception,
    // or it can exit normally and return a result. These outcomes
    // are chosen randomly.
    private int TimeConsumingOperation( 
        BackgroundWorker bw, 
        int sleepPeriod )
    {
        int result = 0;
    
        Random rand = new Random();
    
        while (!bw.CancellationPending)
        {
            bool exit = false;
    
            switch (rand.Next(3))
            {
                // Raise an exception.
                case 0:
                {
                    throw new Exception("An error condition occurred.");
                    break;
                }
    
                // Sleep for the number of milliseconds
                // specified by the sleepPeriod parameter.
                case 1:
                {
                    Thread.Sleep(sleepPeriod);
                    break;
                }
    
                // Exit and return normally.
                case 2:
                {
                    result = 23;
                    exit = true;
                    break;
                }
    
                default:
                {
                    break;
                }
            }
    
            if( exit )
            {
                break;
            }
        }
    
        return result;
    }
    
  10. Windows フォーム デザイナーで startButton をダブルクリックして Click イベント ハンドラーを作成します。

  11. startButton の Click イベント ハンドラーで RunWorkerAsync メソッドを呼び出します。

    Private Sub startButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles startBtn.Click
        Me.backgroundWorker1.RunWorkerAsync(2000)
    End Sub
    
    private void startBtn_Click(object sender, EventArgs e)
    {
        this.backgroundWorker1.RunWorkerAsync(2000);
    }
    
  12. Windows フォーム デザイナーで cancelButton をダブルクリックして Click イベント ハンドラーを作成します。

  13. cancelButton の Click イベント ハンドラーでCancelAsync メソッドを呼び出します。

    Private Sub cancelButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles cancelBtn.Click
        Me.backgroundWorker1.CancelAsync()
    End Sub
    
    private void cancelBtn_Click(object sender, EventArgs e)
    {
        this.backgroundWorker1.CancelAsync();
    }
    
  14. ファイルの先頭に System.ComponentModel and System.Threading 名前空間をインポートします。

    Imports System
    Imports System.ComponentModel
    Imports System.Drawing
    Imports System.Threading
    Imports System.Windows.Forms
    
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Threading;
    using System.Windows.Forms;
    
  15. F6 を押してソリューションをビルドした後で、Ctrl キーを押しながら F5 キーを押してアプリケーションをデバッガーの外部で実行します。

注意

F5 キーを押してアプリケーションをデバッガーの内部で実行した場合、TimeConsumingOperation メソッド内で発生する例外がデバッガーにキャッチされ、表示されます。 アプリケーションをデバッガーの外部で実行すると、BackgroundWorker が例外を処理し、RunWorkerCompletedEventArgsError プロパティにキャッシュします。

  1. 非同期操作を実行するには [開始] をクリックし、非同期操作の実行を停止するには [キャンセル] をクリックします。

    各操作の結果は、MessageBox に表示されます。

次の手順

参照

処理手順

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

方法 : バックグラウンドで操作を実行する

参照

BackgroundWorker

DoWorkEventArgs

その他の技術情報

BackgroundWorker コンポーネント