チュートリアル: バックグラウンド操作を使用するフォームの実装Walkthrough: Implementing a Form That Uses a Background Operation

完了するには長い時間がかかる操作がない場合、したくない、ユーザー インターフェイス (UI) 応答を停止するかブロックするを使用することができます、BackgroundWorkerクラスを別のスレッドで操作を実行します。If you have an operation that will take a long time to complete, and you do not want your user interface (UI) to stop responding or to block, you can use the BackgroundWorker class to execute the operation on another thread.

このチュートリアルで使用する方法、 BackgroundWorker ""バック グラウンドで時間のかかる計算を実行するクラス、ユーザー インターフェイスの応答性の高いままです。This walkthrough illustrates how to use the BackgroundWorker class to perform time-consuming computations "in the background," while the user interface remains responsive. このチュートリアルを完了すると、フィボナッチ数を非同期に計算するアプリケーションが作成されます。When you are through, you will have an application that computes Fibonacci numbers asynchronously. 大きなフィボナッチ数の計算にはかなりの時間がかかることがありますが、この遅延によってメイン UI スレッドが中断されることはなく、計算中もフォームは応答性を維持します。Even though computing a large Fibonacci number can take a noticeable amount of time, the main UI thread will not be interrupted by this delay, and the form will be responsive during the calculation.

このチュートリアルでは、以下のタスクを行います。Tasks illustrated in this walkthrough include:

  • Windows ベースのアプリケーションの作成Creating a Windows-based Application

  • 作成、BackgroundWorkerフォームCreating a BackgroundWorker in Your Form

  • 非同期イベント ハンドラーの追加Adding Asynchronous Event Handlers

  • 進行状況の報告とキャンセルのサポートの追加Adding Progress Reporting and Support for Cancellation

この例で使用するコードの完全な一覧については、次を参照してください。方法。バック グラウンド操作を使用してフォームを実装するします。For a complete listing of the code used in this example, see How to: Implement a Form That Uses a Background Operation.

バック グラウンド操作を使用するフォームを作成します。Create a form that uses a background operation

  1. Visual Studio で、という名前の Windows ベースのアプリケーション プロジェクトを作成BackgroundWorkerExample(ファイル > 新規 > プロジェクト > Visual C# またはVisual Basic > クラシック デスクトップ > Windows フォームアプリケーション)。In Visual Studio, create a Windows-based application project called BackgroundWorkerExample (File > New > Project > Visual C# or Visual Basic > Classic Desktop > Windows Forms Application).

  2. ソリューション エクスプローラーで、 [Form1] を右クリックし、ショートカット メニューの [名前の変更] をクリックします。In Solution Explorer, right-click Form1 and select Rename from the shortcut menu. ファイル名を FibonacciCalculator に変更します。Change the file name to FibonacciCalculator. コード要素 "Form1" へのすべての参照の名前を変更するかどうかをたずねられたら、 [はい] をクリックします。Click the Yes button when you are asked if you want to rename all references to the code element 'Form1'.

  3. ドラッグ、NumericUpDownコントロールから、ツールボックスフォーム上にします。Drag a NumericUpDown control from the Toolbox onto the form. 設定、Minimumプロパティを1Maximumプロパティを91します。Set the Minimum property to 1 and the Maximum property to 91.

  4. 2 つ追加Buttonフォームのコントロール。Add two Button controls to the form.

  5. 最初の名前を変更ButtonコントロールstartAsyncButton設定と、TextプロパティをStart Asyncします。Rename the first Button control startAsyncButton and set the Text property to Start Async. 2 つ目の名前を変更ButtonコントロールcancelAsyncButton、設定、TextプロパティをCancel Asyncします。Rename the second Button control cancelAsyncButton, and set the Text property to Cancel Async. 設定のEnabledプロパティをfalseします。Set its Enabled property to false.

  6. この 2 つのイベント ハンドラーを作成、ButtonコントロールのClickイベント。Create an event handler for both of the Button controls' Click events. 詳細については、「方法: デザイナーを使用してイベント ハンドラーを作成するします。For details, see How to: Create Event Handlers Using the Designer.

  7. ドラッグ、Labelコントロールから、ツールボックスをフォームに名前を変更し、resultLabelします。Drag a Label control from the Toolbox onto the form and rename it resultLabel.

  8. ドラッグ、ProgressBarコントロールから、ツールボックスフォーム上にします。Drag a ProgressBar control from the Toolbox onto the form.

デザイナーでの BackgroundWorker を作成します。Create a BackgroundWorker with the Designer

作成することができます、BackgroundWorkerを使用して、非同期操作のWindows フォーム デザイナーします。You can create the BackgroundWorker for your asynchronous operation using the Windows Forms Designer.

コンポーネントのタブ、ツールボックス、ドラッグ、BackgroundWorkerフォーム上にします。From the Components tab of the Toolbox, drag a BackgroundWorker onto the form.

非同期イベント ハンドラーを追加します。Add asynchronous event handlers

イベント ハンドラーを追加する準備が整いました、BackgroundWorkerコンポーネントの非同期イベント。You are now ready to add event handlers for the BackgroundWorker component's asynchronous events. バックグラウンドで実行される時間のかかる操作 (フィボナッチ数の計算) は、これらのイベント ハンドラーのいずれかによって呼び出されます。The time-consuming operation that will run in the background, which computes Fibonacci numbers, is called by one of these event handlers.

  1. プロパティ ウィンドウで、BackgroundWorkerが選択されているコンポーネントをクリックして、イベントボタン。In the Properties window, with the BackgroundWorker component still selected, click the Events button. ダブルクリックして、DoWorkRunWorkerCompletedイベントをイベント ハンドラーを作成します。Double-click the DoWork and RunWorkerCompleted events to create event handlers. イベント ハンドラーを使用する方法の詳細については、次を参照してください。方法。デザイナーを使用してイベント ハンドラーを作成するします。For more information about how to use event handlers, see How to: Create Event Handlers Using the Designer.

  2. フォームで ComputeFibonacci という新しいメソッドを作成します。Create a new method, called ComputeFibonacci, in your form. このメソッドがバックグラウンドで実行され、実際の処理を行います。This method does the actual work, and it will run in the background. このコードは、フィボナッチ アルゴリズムの再帰的実装を示しています。これは、非常に非効率であり、数が大きくなるにつれて、完了までの所要時間が急激に増大します。This code demonstrates the recursive implementation of the Fibonacci algorithm, which is notably inefficient, taking exponentially longer time to complete for larger numbers. ここでは、アプリケーションで長時間の遅延が発生する可能性のある操作を示すために、このコードを使用しています。It is used here for illustrative purposes, to show an operation that can introduce long delays in your application.

    // This is the method that does the actual work. For this
    // example, it computes a Fibonacci number and
    // reports progress as it does its work.
    long ComputeFibonacci( int n, BackgroundWorker^ worker, DoWorkEventArgs ^ e )
    {
       // The parameter n must be >= 0 and <= 91.
       // Fib(n), with n > 91, overflows a long.
       if ( (n < 0) || (n > 91) )
       {
          throw gcnew ArgumentException( "value must be >= 0 and <= 91","n" );
       }
    
       long result = 0;
       
       // Abort the operation if the user has cancelled.
       // Note that a call to CancelAsync may have set 
       // CancellationPending to true just after the
       // last invocation of this method exits, so this 
       // code will not have the opportunity to set the 
       // DoWorkEventArgs.Cancel flag to true. This means
       // that RunWorkerCompletedEventArgs.Cancelled will
       // not be set to true in your RunWorkerCompleted
       // event handler. This is a race condition.
       if ( worker->CancellationPending )
       {
          e->Cancel = true;
       }
       else
       {
          if ( n < 2 )
          {
             result = 1;
          }
          else
          {
             result = ComputeFibonacci( n - 1, worker, e ) + ComputeFibonacci( n - 2, worker, e );
          }
    
          // Report progress as a percentage of the total task.
          int percentComplete = (int)((float)n / (float)numberToCompute * 100);
          if ( percentComplete > highestPercentageReached )
          {
             highestPercentageReached = percentComplete;
             worker->ReportProgress( percentComplete );
          }
       }
    
       return result;
    }
    
    // This is the method that does the actual work. For this
    // example, it computes a Fibonacci number and
    // reports progress as it does its work.
    long ComputeFibonacci(int n, BackgroundWorker worker, DoWorkEventArgs e)
    {
        // The parameter n must be >= 0 and <= 91.
        // Fib(n), with n > 91, overflows a long.
        if ((n < 0) || (n > 91))
        {
            throw new ArgumentException(
                "value must be >= 0 and <= 91", "n");
        }
    
        long result = 0;
    
        // Abort the operation if the user has canceled.
        // Note that a call to CancelAsync may have set 
        // CancellationPending to true just after the
        // last invocation of this method exits, so this 
        // code will not have the opportunity to set the 
        // DoWorkEventArgs.Cancel flag to true. This means
        // that RunWorkerCompletedEventArgs.Cancelled will
        // not be set to true in your RunWorkerCompleted
        // event handler. This is a race condition.
    
        if (worker.CancellationPending)
        {   
            e.Cancel = true;
        }
        else
        {   
            if (n < 2)
            {   
                result = 1;
            }
            else
            {   
                result = ComputeFibonacci(n - 1, worker, e) + 
                         ComputeFibonacci(n - 2, worker, e);
            }
    
            // Report progress as a percentage of the total task.
            int percentComplete = 
                (int)((float)n / (float)numberToCompute * 100);
            if (percentComplete > highestPercentageReached)
            {
                highestPercentageReached = percentComplete;
                worker.ReportProgress(percentComplete);
            }
        }
    
        return result;
    }
    
    ' This is the method that does the actual work. For this
    ' example, it computes a Fibonacci number and
    ' reports progress as it does its work.
    Function ComputeFibonacci( _
        ByVal n As Integer, _
        ByVal worker As BackgroundWorker, _
        ByVal e As DoWorkEventArgs) As Long
    
        ' The parameter n must be >= 0 and <= 91.
        ' Fib(n), with n > 91, overflows a long.
        If n < 0 OrElse n > 91 Then
            Throw New ArgumentException( _
                "value must be >= 0 and <= 91", "n")
        End If
    
        Dim result As Long = 0
    
        ' Abort the operation if the user has canceled.
        ' Note that a call to CancelAsync may have set 
        ' CancellationPending to true just after the
        ' last invocation of this method exits, so this 
        ' code will not have the opportunity to set the 
        ' DoWorkEventArgs.Cancel flag to true. This means
        ' that RunWorkerCompletedEventArgs.Cancelled will
        ' not be set to true in your RunWorkerCompleted
        ' event handler. This is a race condition.
        If worker.CancellationPending Then
            e.Cancel = True
        Else
            If n < 2 Then
                result = 1
            Else
                result = ComputeFibonacci(n - 1, worker, e) + _
                         ComputeFibonacci(n - 2, worker, e)
            End If
    
            ' Report progress as a percentage of the total task.
            Dim percentComplete As Integer = _
                CSng(n) / CSng(numberToCompute) * 100
            If percentComplete > highestPercentageReached Then
                highestPercentageReached = percentComplete
                worker.ReportProgress(percentComplete)
            End If
    
        End If
    
        Return result
    
    End Function
    
  3. DoWorkイベント ハンドラー呼び出しを追加、ComputeFibonacciメソッド。In the DoWork event handler, add a call to the ComputeFibonacci method. 最初のパラメーターを受け取るComputeFibonacciから、Argumentのプロパティ、DoWorkEventArgsします。Take the first parameter for ComputeFibonacci from the Argument property of the DoWorkEventArgs. BackgroundWorkerDoWorkEventArgsパラメーターが進行状況の報告とキャンセルの後で使用をサポートします。The BackgroundWorker and DoWorkEventArgs parameters will be used later for progress reporting and cancellation support. 戻り値を割り当てるComputeFibonacciResultのプロパティ、DoWorkEventArgsします。Assign the return value from ComputeFibonacci to the Result property of the DoWorkEventArgs. この結果は、使用可能になります、RunWorkerCompletedイベント ハンドラー。This result will be available to the RunWorkerCompleted event handler.

    注意

    DoWorkイベント ハンドラーを参照していません、backgroundWorker1の特定のインスタンスにこのイベント ハンドラーを結合はこのように、変数を直接インスタンスBackgroundWorkerします。The DoWork event handler does not reference the backgroundWorker1 instance variable directly, as this would couple this event handler to a specific instance of BackgroundWorker. 代わりへの参照、BackgroundWorkerこれが発生したイベントがから復元、senderパラメーター。Instead, a reference to the BackgroundWorker that raised this event is recovered from the sender parameter. これは、1 つ以上のフォームがホストされる場合に重要なBackgroundWorkerします。This is important when the form hosts more than one BackgroundWorker. 内の任意のユーザー インターフェイス オブジェクトを操作しないようにする重要なも、DoWorkイベント ハンドラー。It is also important not to manipulate any user-interface objects in your DoWork event handler. 代わりに、を通じてユーザー インターフェイスとの通信、BackgroundWorkerイベント。Instead, communicate to the user interface through the BackgroundWorker events.

    // 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 = 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 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
    
  4. startAsyncButtonコントロールのClickイベント ハンドラー、非同期操作を開始するコードを追加します。In the startAsyncButton control's Click event handler, add the code that starts the asynchronous operation.

    void startAsyncButton_Click( System::Object^ /*sender*/, System::EventArgs^ /*e*/ )
    {
       
       // Reset the text in the result label.
       resultLabel->Text = String::Empty;
    
       // Disable the UpDown control until 
       // the asynchronous operation is done.
       this->numericUpDown1->Enabled = false;
    
       // Disable the Start button until 
       // the asynchronous operation is done.
       this->startAsyncButton->Enabled = false;
    
       // Enable the Cancel button while 
       // the asynchronous operation runs.
       this->cancelAsyncButton->Enabled = true;
    
       // Get the value from the UpDown control.
       numberToCompute = (int)numericUpDown1->Value;
    
       // Reset the variable for percentage tracking.
       highestPercentageReached = 0;
    
       // Start the asynchronous operation.
       backgroundWorker1->RunWorkerAsync( numberToCompute );
    }
    
    private void startAsyncButton_Click(System.Object sender, 
        System.EventArgs e)
    {
        // Reset the text in the result label.
        resultLabel.Text = String.Empty;
    
        // Disable the UpDown control until 
        // the asynchronous operation is done.
        this.numericUpDown1.Enabled = false;
    
        // Disable the Start button until 
        // the asynchronous operation is done.
        this.startAsyncButton.Enabled = false;
    
        // Enable the Cancel button while 
        // the asynchronous operation runs.
        this.cancelAsyncButton.Enabled = true;
    
        // Get the value from the UpDown control.
        numberToCompute = (int)numericUpDown1.Value;
    
        // Reset the variable for percentage tracking.
        highestPercentageReached = 0;
    
        // Start the asynchronous operation.
        backgroundWorker1.RunWorkerAsync(numberToCompute);
    }
    
    Private Sub startAsyncButton_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) _
    Handles startAsyncButton.Click
    
        ' Reset the text in the result label.
        resultLabel.Text = [String].Empty
    
        ' Disable the UpDown control until 
        ' the asynchronous operation is done.
        Me.numericUpDown1.Enabled = False
    
        ' Disable the Start button until 
        ' the asynchronous operation is done.
        Me.startAsyncButton.Enabled = False
    
        ' Enable the Cancel button while 
        ' the asynchronous operation runs.
        Me.cancelAsyncButton.Enabled = True
    
        ' Get the value from the UpDown control.
        numberToCompute = CInt(numericUpDown1.Value)
    
        ' Reset the variable for percentage tracking.
        highestPercentageReached = 0
    
    
        ' Start the asynchronous operation.
        backgroundWorker1.RunWorkerAsync(numberToCompute)
    End Sub 
    
  5. RunWorkerCompletedイベント ハンドラーでは、計算の結果に割り当てる、resultLabelコントロール。In the RunWorkerCompleted event handler, assign the result of the calculation to the resultLabel control.

    // This event handler deals with the results of the
    // background operation.
    void backgroundWorker1_RunWorkerCompleted( Object^ /*sender*/, RunWorkerCompletedEventArgs^ e )
    {
       // First, handle the case where an exception was thrown.
       if ( e->Error != nullptr )
       {
          MessageBox::Show( e->Error->Message );
       }
       else
       if ( e->Cancelled )
       {
          // Next, handle the case where the user cancelled 
          // the operation.
          // Note that due to a race condition in 
          // the DoWork event handler, the Cancelled
          // flag may not have been set, even though
          // CancelAsync was called.
          resultLabel->Text = "Cancelled";
       }
       else
       {
          // Finally, handle the case where the operation 
          // succeeded.
          resultLabel->Text = e->Result->ToString();
       }
    
       // Enable the UpDown control.
       this->numericUpDown1->Enabled = true;
    
       // Enable the Start button.
       startAsyncButton->Enabled = true;
    
       // Disable the Cancel button.
       cancelAsyncButton->Enabled = false;
    }
    
    // This event handler deals with the results of the
    // background operation.
    private void backgroundWorker1_RunWorkerCompleted(
        object sender, RunWorkerCompletedEventArgs e)
    {
        // First, handle the case where an exception was thrown.
        if (e.Error != null)
        {
            MessageBox.Show(e.Error.Message);
        }
        else if (e.Cancelled)
        {
            // Next, handle the case where the user canceled 
            // the operation.
            // Note that due to a race condition in 
            // the DoWork event handler, the Cancelled
            // flag may not have been set, even though
            // CancelAsync was called.
            resultLabel.Text = "Canceled";
        }
        else
        {
            // Finally, handle the case where the operation 
            // succeeded.
            resultLabel.Text = e.Result.ToString();
        }
    
        // Enable the UpDown control.
        this.numericUpDown1.Enabled = true;
    
        // Enable the Start button.
        startAsyncButton.Enabled = true;
    
        // Disable the Cancel button.
        cancelAsyncButton.Enabled = false;
    }
    
    ' This event handler deals with the results of the
    ' background operation.
    Private Sub backgroundWorker1_RunWorkerCompleted( _
    ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) _
    Handles backgroundWorker1.RunWorkerCompleted
    
        ' First, handle the case where an exception was thrown.
        If (e.Error IsNot Nothing) Then
            MessageBox.Show(e.Error.Message)
        ElseIf e.Cancelled Then
            ' Next, handle the case where the user canceled the 
            ' operation.
            ' Note that due to a race condition in 
            ' the DoWork event handler, the Cancelled
            ' flag may not have been set, even though
            ' CancelAsync was called.
            resultLabel.Text = "Canceled"
        Else
            ' Finally, handle the case where the operation succeeded.
            resultLabel.Text = e.Result.ToString()
        End If
    
        ' Enable the UpDown control.
        Me.numericUpDown1.Enabled = True
    
        ' Enable the Start button.
        startAsyncButton.Enabled = True
    
        ' Disable the Cancel button.
        cancelAsyncButton.Enabled = False
    End Sub
    

進行状況の報告とキャンセルのサポートの追加Adding Progress Reporting and Support for Cancellation

時間のかかる非同期操作では、多くの場合、進行状況をユーザーに報告し、ユーザーが操作をキャンセルできるようにすることが望まれます。For asynchronous operations that will take a long time, it is often desirable to report progress to the user and to allow the user to cancel the operation. BackgroundWorkerクラスは、バック グラウンド操作処理の進行状況の進行状況を投稿できるイベントを提供します。The BackgroundWorker class provides an event that allows you to post progress as your background operation proceeds. 呼び出しを検出するために、ワーカー コードを許可するフラグも用意されています。CancelAsync自体を中断するとします。It also provides a flag that allows your worker code to detect a call to CancelAsync and interrupt itself.

進行状況レポートを実装します。Implement progress reporting

  1. [プロパティ] ウィンドウで backgroundWorker1 を選択します。In the Properties, window, select backgroundWorker1. WorkerReportsProgressWorkerSupportsCancellation プロパティを true\ に設定します。Set the WorkerReportsProgress and WorkerSupportsCancellation properties to true.

  2. FibonacciCalculator フォームで 2 つの変数を宣言します。Declare two variables in the FibonacciCalculator form. これらの変数を使用して進行状況を追跡します。These will be used to track progress.

    int numberToCompute;
    int highestPercentageReached;
    
    private int numberToCompute = 0;
    private int highestPercentageReached = 0;
    
    Private numberToCompute As Integer = 0
    Private highestPercentageReached As Integer = 0
    
  3. ProgressChanged イベントのイベント ハンドラーを追加します。Add an event handler for the ProgressChanged event. ProgressChangedイベント ハンドラー、update、ProgressBarで、ProgressPercentageのプロパティ、ProgressChangedEventArgsパラメーター。In the ProgressChanged event handler, update the ProgressBar with the ProgressPercentage property of the ProgressChangedEventArgs parameter.

    // This event handler updates the progress bar.
    void backgroundWorker1_ProgressChanged( Object^ /*sender*/, ProgressChangedEventArgs^ e )
    {
       this->progressBar1->Value = e->ProgressPercentage;
    }
    
    // This event handler updates the progress bar.
    private void backgroundWorker1_ProgressChanged(object sender,
        ProgressChangedEventArgs e)
    {
        this.progressBar1.Value = e.ProgressPercentage;
    }
    
    ' This event handler updates the progress bar.
    Private Sub backgroundWorker1_ProgressChanged( _
    ByVal sender As Object, ByVal e As ProgressChangedEventArgs) _
    Handles backgroundWorker1.ProgressChanged
    
        Me.progressBar1.Value = e.ProgressPercentage
    
    End Sub
    

キャンセルのサポートを実装します。Implement support for cancellation

  1. cancelAsyncButtonコントロールのClickイベント ハンドラー、非同期操作をキャンセルするコードを追加します。In the cancelAsyncButton control's Click event handler, add the code that cancels the asynchronous operation.

    void cancelAsyncButton_Click( System::Object^ /*sender*/, System::EventArgs^ /*e*/ )
    {  
       // Cancel the asynchronous operation.
       this->backgroundWorker1->CancelAsync();
       
       // Disable the Cancel button.
       cancelAsyncButton->Enabled = false;
    }
    
    private void cancelAsyncButton_Click(System.Object sender, 
        System.EventArgs e)
    {   
        // Cancel the asynchronous operation.
        this.backgroundWorker1.CancelAsync();
    
        // Disable the Cancel button.
        cancelAsyncButton.Enabled = false;
    }
    
    Private Sub cancelAsyncButton_Click( _
    ByVal sender As System.Object, _
    ByVal e As System.EventArgs) _
    Handles cancelAsyncButton.Click
        
        ' Cancel the asynchronous operation.
        Me.backgroundWorker1.CancelAsync()
    
        ' Disable the Cancel button.
        cancelAsyncButton.Enabled = False
        
    End Sub
    
  2. ComputeFibonacci メソッドの次のコード フラグメントは、進行状況の報告とキャンセルのサポートを示しています。The following code fragments in the ComputeFibonacci method report progress and support cancellation.

    if ( worker->CancellationPending )
    {
       e->Cancel = true;
    }
    
    if (worker.CancellationPending)
    {   
        e.Cancel = true;
    }
    
    If worker.CancellationPending Then
        e.Cancel = True
    
    // Report progress as a percentage of the total task.
    int percentComplete = (int)((float)n / (float)numberToCompute * 100);
    if ( percentComplete > highestPercentageReached )
    {
       highestPercentageReached = percentComplete;
       worker->ReportProgress( percentComplete );
    }
    
    // Report progress as a percentage of the total task.
    int percentComplete = 
        (int)((float)n / (float)numberToCompute * 100);
    if (percentComplete > highestPercentageReached)
    {
        highestPercentageReached = percentComplete;
        worker.ReportProgress(percentComplete);
    }
    
    ' Report progress as a percentage of the total task.
    Dim percentComplete As Integer = _
        CSng(n) / CSng(numberToCompute) * 100
    If percentComplete > highestPercentageReached Then
        highestPercentageReached = percentComplete
        worker.ReportProgress(percentComplete)
    End If
    

チェックポイントCheckpoint

この時点で、フィボナッチ電卓アプリケーションをコンパイルして実行できます。At this point, you can compile and run the Fibonacci Calculator application.

キーを押してF5をコンパイルして、アプリケーションを実行します。Press F5 to compile and run the application.

計算がバック グラウンドで実行しているときに表示されます、ProgressBar完了するまでの進行状況を表示します。While the calculation is running in the background, you will see the ProgressBar displaying the progress of the calculation toward completion. また、保留中の操作をキャンセルすることもできます。You can also cancel the pending operation.

数値が小さい場合、計算に時間はかかりませんが、数値が大きくなると、大幅な遅延が発生します。For small numbers, the calculation should be very fast, but for larger numbers, you should see a noticeable delay. 30 以上の値を入力した場合、コンピューターの速度によっては数秒の遅延が発生します。If you enter a value of 30 or greater, you should see a delay of several seconds, depending on the speed of your computer. 値が 40 を超えると、計算が終了するまでに数分から数時間かかることがあります。For values greater than 40, it may take minutes or hours to finish the calculation. 電卓が大きなフィボナッチ数を計算している間も、フォームの移動、最小化、最大化を自由に行うことができ、フォームを閉じることもできます。While the calculator is busy computing a large Fibonacci number, notice that you can freely move the form around, minimize, maximize, and even dismiss it. これは、メイン UI スレッドが計算の終了を待機していないためです。This is because the main UI thread is not waiting for the calculation to finish.

次の手順Next steps

使用するフォームを実装している、BackgroundWorkerバック グラウンドで計算を実行するコンポーネントの他の非同期操作の可能性を調べることができます。Now that you have implemented a form that uses a BackgroundWorker component to execute a computation in the background, you can explore other possibilities for asynchronous operations:

関連項目See also