평가 및 의견을 보내려면 클릭하십시오.
MSDN
MSDN Library
.NET 개발
이전 버전
.NET Framework SDK 2.0
Class Library Reference
System.ComponentModel
BackgroundWorker 클래스

  저대역폭 보기 설정
이 페이지에서 다루는 특정 제품:.
Microsoft Visual Studio 2005/.NET Framework 2.0

다음 제품들은 다른 버전에서 다루어 집니다.
.NET Framework 클래스 라이브러리
BackgroundWorker 클래스

참고: 이 클래스는 .NET Framework 버전 2.0에서 새로 추가되었습니다.

별도의 스레드에서 작업을 실행합니다.

네임스페이스: System.ComponentModel
어셈블리: System(system.dll)

Visual Basic(선언)
Public Class BackgroundWorker
    Inherits Component
Visual Basic(사용법)
Dim instance As BackgroundWorker
C#
public class BackgroundWorker : Component
C++
public ref class BackgroundWorker : public Component
J#
public class BackgroundWorker extends Component
JScript
public class BackgroundWorker extends Component

BackgroundWorker 클래스를 사용하면 별도의 전용 스레드에서 작업을 실행할 수 있습니다. 다운로드 및 데이터베이스 트랜잭션과 같은 시간이 많이 걸리는 작업이 실행되는 동안에는 UI(사용자 인터페이스)가 응답을 중지한 것처럼 보일 수 있습니다. UI의 응답 속도를 높이려 하고 이러한 작업과 관련된 지연 시간이 길어지는 경우 BackgroundWorker 클래스는 간편한 해결책을 제공합니다.

백그라운드에서 시간이 많이 걸리는 작업을 실행하려면 BackgroundWorker를 만든 다음 작업의 진행률을 보고하고 작업이 끝날 때 알리는 이벤트를 수신합니다. 프로그래밍 방식으로 BackgroundWorker를 만들거나 이 개체를 도구 상자구성 요소 탭에서 폼으로 끌어 올 수 있습니다. Windows Forms 디자이너에서 BackgroundWorker를 만들면 이 개체가 구성 요소 트레이에 나타나고 해당 속성이 속성 창에 표시됩니다.

백그라운드 작업을 설정하려면 DoWork 이벤트의 이벤트 처리기를 추가한 다음 이 이벤트 처리기에서 시간이 많이 걸리는 작업을 호출합니다. 작업을 시작하려면 RunWorkerAsync를 호출하고, 진행률 업데이트에 대한 알림을 받으려면 ProgressChanged 이벤트를 처리합니다. 작업이 완료될 때 알림을 받으려면 RunWorkerCompleted 이벤트를 처리합니다.

Note참고

DoWork 이벤트 처리기에서 사용자 인터페이스 개체를 조작하지 않도록 주의해야 합니다. 대신 ProgressChangedRunWorkerCompleted 이벤트를 통해 사용자 인터페이스와 통신합니다.

BackgroundWorker 이벤트는 AppDomain 경계를 넘어 마샬링되지 않습니다. BackgroundWorker 구성 요소를 사용하여 둘 이상의 AppDomain에서 다중 스레드 작업을 수행하지 마십시오.

백그라운드 작업에 매개 변수가 필요하면 매개 변수를 사용하여 RunWorkerAsync를 호출합니다. DoWork 이벤트 처리기 안에 있는 DoWorkEventArgs.Argument 속성에서 매개 변수를 추출할 수 있습니다.

BackgroundWorker에 대한 자세한 내용은 방법: 백그라운드에서 작업 실행을 참조하십시오.

Note참고

이 클래스에 적용되는 HostProtectionAttribute 특성의 Resources 속성 값은 SharedState입니다. HostProtectionAttribute는 대개 아이콘을 두 번 클릭하거나, 명령을 입력하거나, 브라우저에서 URL을 입력하여 시작되는 데스크톱 응용 프로그램에 영향을 미치지 않습니다. 자세한 내용은 HostProtectionAttribute 클래스나 SQL Server 프로그래밍 및 호스트 보호 특성을 참조하십시오.

다음 코드 예제에서는 BackgroundWorker 클래스를 사용하여 시간이 많이 걸리는 작업을 비동기적으로 실행하는 방법을 보여 줍니다. 작업에서는 선택된 피바노치(Fibonacci) 수를 계산하고 계산이 진행됨에 따라 진행률 업데이트를 보고하며 보류 중인 계산을 취소할 수 있도록 합니다.

Visual Basic
Imports System
Imports System.Collections
Imports System.ComponentModel
Imports System.Drawing
Imports System.Threading
Imports System.Windows.Forms

Public Class FibonacciForm
    Inherits System.Windows.Forms.Form

    Private numberToCompute As Integer = 0
    Private highestPercentageReached As Integer = 0

    Private numericUpDown1 As System.Windows.Forms.NumericUpDown
    Private WithEvents startAsyncButton As System.Windows.Forms.Button
    Private WithEvents cancelAsyncButton As System.Windows.Forms.Button
    Private progressBar1 As System.Windows.Forms.ProgressBar
    Private resultLabel As System.Windows.Forms.Label
    Private WithEvents backgroundWorker1 As System.ComponentModel.BackgroundWorker


    Public Sub New()
        InitializeComponent()
    End Sub 'New

    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 

    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 'cancelAsyncButton_Click

    ' 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 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 Not (e.Error Is 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 'backgroundWorker1_RunWorkerCompleted

    ' 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

    ' 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


    Private Sub InitializeComponent()
        Me.numericUpDown1 = New System.Windows.Forms.NumericUpDown
        Me.startAsyncButton = New System.Windows.Forms.Button
        Me.cancelAsyncButton = New System.Windows.Forms.Button
        Me.resultLabel = New System.Windows.Forms.Label
        Me.progressBar1 = New System.Windows.Forms.ProgressBar
        Me.backgroundWorker1 = New System.ComponentModel.BackgroundWorker
        CType(Me.numericUpDown1, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'numericUpDown1
        '
        Me.numericUpDown1.Location = New System.Drawing.Point(16, 16)
        Me.numericUpDown1.Maximum = New Decimal(New Integer() {91, 0, 0, 0})
        Me.numericUpDown1.Minimum = New Decimal(New Integer() {1, 0, 0, 0})
        Me.numericUpDown1.Name = "numericUpDown1"
        Me.numericUpDown1.Size = New System.Drawing.Size(80, 20)
        Me.numericUpDown1.TabIndex = 0
        Me.numericUpDown1.Value = New Decimal(New Integer() {1, 0, 0, 0})
        '
        'startAsyncButton
        '
        Me.startAsyncButton.Location = New System.Drawing.Point(16, 72)
        Me.startAsyncButton.Name = "startAsyncButton"
        Me.startAsyncButton.Size = New System.Drawing.Size(120, 23)
        Me.startAsyncButton.TabIndex = 1
        Me.startAsyncButton.Text = "Start Async"
        '
        'cancelAsyncButton
        '
        Me.cancelAsyncButton.Enabled = False
        Me.cancelAsyncButton.Location = New System.Drawing.Point(153, 72)
        Me.cancelAsyncButton.Name = "cancelAsyncButton"
        Me.cancelAsyncButton.Size = New System.Drawing.Size(119, 23)
        Me.cancelAsyncButton.TabIndex = 2
        Me.cancelAsyncButton.Text = "Cancel Async"
        '
        'resultLabel
        '
        Me.resultLabel.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D
        Me.resultLabel.Location = New System.Drawing.Point(112, 16)
        Me.resultLabel.Name = "resultLabel"
        Me.resultLabel.Size = New System.Drawing.Size(160, 23)
        Me.resultLabel.TabIndex = 3
        Me.resultLabel.Text = "(no result)"
        Me.resultLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
        '
        'progressBar1
        '
        Me.progressBar1.Location = New System.Drawing.Point(18, 48)
        Me.progressBar1.Name = "progressBar1"
        Me.progressBar1.Size = New System.Drawing.Size(256, 8)
        Me.progressBar1.TabIndex = 4
        '
        'backgroundWorker1
        '
        Me.backgroundWorker1.WorkerReportsProgress = True
        Me.backgroundWorker1.WorkerSupportsCancellation = True
        '
        'FibonacciForm
        '
        Me.ClientSize = New System.Drawing.Size(292, 118)
        Me.Controls.Add(Me.progressBar1)
        Me.Controls.Add(Me.resultLabel)
        Me.Controls.Add(Me.cancelAsyncButton)
        Me.Controls.Add(Me.startAsyncButton)
        Me.Controls.Add(Me.numericUpDown1)
        Me.Name = "FibonacciForm"
        Me.Text = "Fibonacci Calculator"
        CType(Me.numericUpDown1, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)

    End Sub 'InitializeComponent

    <STAThread()> _
    Shared Sub Main()
        Application.Run(New FibonacciForm)
    End Sub 'Main
End Class 'FibonacciForm 

C#
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;

namespace BackgroundWorkerExample
{    
    public class FibonacciForm : System.Windows.Forms.Form
    {    
        private int numberToCompute = 0;
        private int highestPercentageReached = 0;

        private System.Windows.Forms.NumericUpDown numericUpDown1;
        private System.Windows.Forms.Button startAsyncButton;
        private System.Windows.Forms.Button cancelAsyncButton;
        private System.Windows.Forms.ProgressBar progressBar1;
        private System.Windows.Forms.Label resultLabel;
        private System.ComponentModel.BackgroundWorker backgroundWorker1;

        public FibonacciForm()
        {    
            InitializeComponent();

            InitializeBackgoundWorker();
        }

        // Set up the BackgroundWorker object by 
        // attaching event handlers. 
        private void InitializeBackgoundWorker()
        {
            backgroundWorker1.DoWork += 
                new DoWorkEventHandler(backgroundWorker1_DoWork);
            backgroundWorker1.RunWorkerCompleted += 
                new RunWorkerCompletedEventHandler(
            backgroundWorker1_RunWorkerCompleted);
            backgroundWorker1.ProgressChanged += 
                new ProgressChangedEventHandler(
            backgroundWorker1_ProgressChanged);
        }
    
        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 void cancelAsyncButton_Click(System.Object sender, 
            System.EventArgs e)
        {   
            // Cancel the asynchronous operation.
            this.backgroundWorker1.CancelAsync();

            // Disable the Cancel button.
            cancelAsyncButton.Enabled = false;
        }

        // 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 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 updates the progress bar.
        private void backgroundWorker1_ProgressChanged(object sender,
            ProgressChangedEventArgs e)
        {
            this.progressBar1.Value = e.ProgressPercentage;
        }

        // 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;
        }


        #region Windows Form Designer generated code
        
        private void InitializeComponent()
        {
            this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
            this.startAsyncButton = new System.Windows.Forms.Button();
            this.cancelAsyncButton = new System.Windows.Forms.Button();
            this.resultLabel = new System.Windows.Forms.Label();
            this.progressBar1 = new System.Windows.Forms.ProgressBar();
            this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
            ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
            this.SuspendLayout();
            // 
            // numericUpDown1
            // 
            this.numericUpDown1.Location = new System.Drawing.Point(16, 16);
            this.numericUpDown1.Maximum = new System.Decimal(new int[] {
            91,
            0,
            0,
            0});
            this.numericUpDown1.Minimum = new System.Decimal(new int[] {
            1,
            0,
            0,
            0});
            this.numericUpDown1.Name = "numericUpDown1";
            this.numericUpDown1.Size = new System.Drawing.Size(80, 20);
            this.numericUpDown1.TabIndex = 0;
            this.numericUpDown1.Value = new System.Decimal(new int[] {
            1,
            0,
            0,
            0});
            // 
            // startAsyncButton
            // 
            this.startAsyncButton.Location = new System.Drawing.Point(16, 72);
            this.startAsyncButton.Name = "startAsyncButton";
            this.startAsyncButton.Size = new System.Drawing.Size(120, 23);
            this.startAsyncButton.TabIndex = 1;
            this.startAsyncButton.Text = "Start Async";
            this.startAsyncButton.Click += new System.EventHandler(this.startAsyncButton_Click);
            // 
            // cancelAsyncButton
            // 
            this.cancelAsyncButton.Enabled = false;
            this.cancelAsyncButton.Location = new System.Drawing.Point(153, 72);
            this.cancelAsyncButton.Name = "cancelAsyncButton";
            this.cancelAsyncButton.Size = new System.Drawing.Size(119, 23);
            this.cancelAsyncButton.TabIndex = 2;
            this.cancelAsyncButton.Text = "Cancel Async";
            this.cancelAsyncButton.Click += new System.EventHandler(this.cancelAsyncButton_Click);
            // 
            // resultLabel
            // 
            this.resultLabel.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
            this.resultLabel.Location = new System.Drawing.Point(112, 16);
            this.resultLabel.Name = "resultLabel";
            this.resultLabel.Size = new System.Drawing.Size(160, 23);
            this.resultLabel.TabIndex = 3;
            this.resultLabel.Text = "(no result)";
            this.resultLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // progressBar1
            // 
            this.progressBar1.Location = new System.Drawing.Point(18, 48);
            this.progressBar1.Name = "progressBar1";
            this.progressBar1.Size = new System.Drawing.Size(256, 8);
            this.progressBar1.Step = 2;
            this.progressBar1.TabIndex = 4;
            // 
            // backgroundWorker1
            // 
            this.backgroundWorker1.WorkerReportsProgress = true;
            this.backgroundWorker1.WorkerSupportsCancellation = true;
            // 
            // FibonacciForm
            // 
            this.ClientSize = new System.Drawing.Size(292, 118);
            this.Controls.Add(this.progressBar1);
            this.Controls.Add(this.resultLabel);
            this.Controls.Add(this.cancelAsyncButton);
            this.Controls.Add(this.startAsyncButton);
            this.Controls.Add(this.numericUpDown1);
            this.Name = "FibonacciForm";
            this.Text = "Fibonacci Calculator";
            ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
            this.ResumeLayout(false);

        }
        #endregion

        [STAThread]
        static void Main()
        {
            Application.Run(new FibonacciForm());
        }
    }
}
C++
#using <System.Drawing.dll>
#using <System.dll>
#using <System.Windows.Forms.dll>

using namespace System;
using namespace System::Collections;
using namespace System::ComponentModel;
using namespace System::Drawing;
using namespace System::Threading;
using namespace System::Windows::Forms;

public ref class FibonacciForm: public System::Windows::Forms::Form
{
private:

   int numberToCompute;
   int highestPercentageReached;

   System::Windows::Forms::NumericUpDown^ numericUpDown1;
   System::Windows::Forms::Button^ startAsyncButton;
   System::Windows::Forms::Button^ cancelAsyncButton;
   System::Windows::Forms::ProgressBar^ progressBar1;
   System::Windows::Forms::Label ^ resultLabel;
   System::ComponentModel::BackgroundWorker^ backgroundWorker1;

public:
   FibonacciForm()
   {
      InitializeComponent();
      numberToCompute = highestPercentageReached = 0;
      InitializeBackgoundWorker();
   }


private:

   // Set up the BackgroundWorker object by 
   // attaching event handlers. 
   void InitializeBackgoundWorker()
   {
      backgroundWorker1->DoWork += gcnew DoWorkEventHandler( this, &FibonacciForm::backgroundWorker1_DoWork );
      backgroundWorker1->RunWorkerCompleted += gcnew RunWorkerCompletedEventHandler( this, &FibonacciForm::backgroundWorker1_RunWorkerCompleted );
      backgroundWorker1->ProgressChanged += gcnew ProgressChangedEventHandler( this, &FibonacciForm::backgroundWorker1_ProgressChanged );
   }

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

   void cancelAsyncButton_Click( System::Object^ /*sender*/, System::EventArgs^ /*e*/ )
   {  
      // Cancel the asynchronous operation.
      this->backgroundWorker1->CancelAsync();
      
      // Disable the Cancel button.
      cancelAsyncButton->Enabled = false;
   }

   // 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 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 updates the progress bar.
   void backgroundWorker1_ProgressChanged( Object^ /*sender*/, ProgressChangedEventArgs^ e )
   {
      this->progressBar1->Value = e->ProgressPercentage;
   }

   // 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;
   }

   void InitializeComponent()
   {
      this->numericUpDown1 = gcnew System::Windows::Forms::NumericUpDown;
      this->startAsyncButton = gcnew System::Windows::Forms::Button;
      this->cancelAsyncButton = gcnew System::Windows::Forms::Button;
      this->resultLabel = gcnew System::Windows::Forms::Label;
      this->progressBar1 = gcnew System::Windows::Forms::ProgressBar;
      this->backgroundWorker1 = gcnew System::ComponentModel::BackgroundWorker;
      (dynamic_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown1))->BeginInit();
      this->SuspendLayout();
      
      // 
      // numericUpDown1
      // 
      this->numericUpDown1->Location = System::Drawing::Point( 16, 16 );
      array<Int32>^temp0 = {91,0,0,0};
      this->numericUpDown1->Maximum = System::Decimal( temp0 );
      array<Int32>^temp1 = {1,0,0,0};
      this->numericUpDown1->Minimum = System::Decimal( temp1 );
      this->numericUpDown1->Name = "numericUpDown1";
      this->numericUpDown1->Size = System::Drawing::Size( 80, 20 );
      this->numericUpDown1->TabIndex = 0;
      array<Int32>^temp2 = {1,0,0,0};
      this->numericUpDown1->Value = System::Decimal( temp2 );

      // 
      // startAsyncButton
      // 
      this->startAsyncButton->Location = System::Drawing::Point( 16, 72 );
      this->startAsyncButton->Name = "startAsyncButton";
      this->startAsyncButton->Size = System::Drawing::Size( 120, 23 );
      this->startAsyncButton->TabIndex = 1;
      this->startAsyncButton->Text = "Start Async";
      this->startAsyncButton->Click += gcnew System::EventHandler( this, &FibonacciForm::startAsyncButton_Click );

      // 
      // cancelAsyncButton
      // 
      this->cancelAsyncButton->Enabled = false;
      this->cancelAsyncButton->Location = System::Drawing::Point( 153, 72 );
      this->cancelAsyncButton->Name = "cancelAsyncButton";
      this->cancelAsyncButton->Size = System::Drawing::Size( 119, 23 );
      this->cancelAsyncButton->TabIndex = 2;
      this->cancelAsyncButton->Text = "Cancel Async";
      this->cancelAsyncButton->Click += gcnew System::EventHandler( this, &FibonacciForm::cancelAsyncButton_Click );

      // 
      // resultLabel
      // 
      this->resultLabel->BorderStyle = System::Windows::Forms::BorderStyle::Fixed3D;
      this->resultLabel->Location = System::Drawing::Point( 112, 16 );
      this->resultLabel->Name = "resultLabel";
      this->resultLabel->Size = System::Drawing::Size( 160, 23 );
      this->resultLabel->TabIndex = 3;
      this->resultLabel->Text = "(no result)";
      this->resultLabel->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;

      // 
      // progressBar1
      // 
      this->progressBar1->Location = System::Drawing::Point( 18, 48 );
      this->progressBar1->Name = "progressBar1";
      this->progressBar1->Size = System::Drawing::Size( 256, 8 );
      this->progressBar1->Step = 2;
      this->progressBar1->TabIndex = 4;

      // 
      // backgroundWorker1
      // 
      this->backgroundWorker1->WorkerReportsProgress = true;
      this->backgroundWorker1->WorkerSupportsCancellation = true;

      // 
      // FibonacciForm
      // 
      this->ClientSize = System::Drawing::Size( 292, 118 );
      this->Controls->Add( this->progressBar1 );
      this->Controls->Add( this->resultLabel );
      this->Controls->Add( this->cancelAsyncButton );
      this->Controls->Add( this->startAsyncButton );
      this->Controls->Add( this->numericUpDown1 );
      this->Name = "FibonacciForm";
      this->Text = "Fibonacci Calculator";
      (dynamic_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown1))->EndInit();
      this->ResumeLayout( false );
   }
};

[STAThread]
int main()
{
   Application::Run( gcnew FibonacciForm );
}
J#
import System.* ;
import System.Collections.* ;
import System.ComponentModel.* ;
import System.Drawing.* ;
import System.Threading.* ;
import System.Windows.Forms.* ;

public class FibonacciForm extends System.Windows.Forms.Form
{
    private int numberToCompute = 0;
    private int highestPercentageReached = 0;

    private System.Windows.Forms.NumericUpDown numericUpDown1;
    private System.Windows.Forms.Button startAsyncButton;
    private System.Windows.Forms.Button cancelAsyncButton;
    private System.Windows.Forms.ProgressBar progressBar1;
    private System.Windows.Forms.Label resultLabel;
    private System.ComponentModel.BackgroundWorker backgroundWorker1;

    public FibonacciForm()
    {
        InitializeComponent();
        InitializeBackgoundWorker();
    } //FibonacciForm

    // Set up the BackgroundWorker object by 
    // attaching event handlers. 
    private void InitializeBackgoundWorker()
    {
        backgroundWorker1.add_DoWork(new DoWorkEventHandler(
            backgroundWorker1_DoWork));
        backgroundWorker1.add_RunWorkerCompleted(
            new RunWorkerCompletedEventHandler(
            backgroundWorker1_RunWorkerCompleted));
        backgroundWorker1.add_ProgressChanged(
            new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged));
    } //InitializeBackgoundWorker

    private void startAsyncButton_Click(Object sender, EventArgs e)
    {
        // Reset the text in the result label.
        resultLabel.set_Text(String.Empty);

        // Disable the UpDown control until 
        // the asynchronous operation is done.
        this.numericUpDown1.set_Enabled(false);

        // Disable the Start button until 
        // the asynchronous operation is done.
        this.startAsyncButton.set_Enabled(false);

        // Enable the Cancel button while 
        // the asynchronous operation runs.
        this.cancelAsyncButton.set_Enabled(true);

        // Get the value from the UpDown control.
        numberToCompute = System.Convert.ToInt32((numericUpDown1.get_Value()));

        // Reset the variable for percentage tracking.
        highestPercentageReached = 0;

        // Start the asynchronous operation.
        backgroundWorker1.RunWorkerAsync(System.Convert.ToString
            (numberToCompute));
    }
    
    private void cancelAsyncButton_Click(Object sender, System.EventArgs e)
    {   
        // Cancel the asynchronous operation.
        this.backgroundWorker1.CancelAsync();

        // Disable the Cancel button.
        cancelAsyncButton.set_Enabled(false);
    }


    // 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

    // 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.get_Error() != null) {
        
            MessageBox.Show(e.get_Error().get_Message());
        }
        else {
        
            if (e.get_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.set_Text("Cancelled");
            }
            else {
            
                // Finally, handle the case where the operation 
                // succeeded.
                resultLabel.set_Text(e.get_Result().ToString());
            }
        }

        // Enable the UpDown control.
        this.numericUpDown1.set_Enabled(true);

        // Enable the Start button.
        startAsyncButton.set_Enabled(true);

        // Disable the Cancel button.
        cancelAsyncButton.set_Enabled(false);
    } //backgroundWorker1_RunWorkerCompleted

    // This event handler updates the progress bar.
    private void backgroundWorker1_ProgressChanged(Object sender,
        ProgressChangedEventArgs e)
    {
        this.progressBar1.set_Value(e.get_ProgressPercentage());
    } //backgroundWorker1_ProgressChanged

    // 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 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.get_CancellationPending()) {
        
            e.set_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;
    } 

    #region Windows Form Designer generated code
    private void InitializeComponent()
    {
        this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
        this.startAsyncButton = new System.Windows.Forms.Button();
        this.cancelAsyncButton = new System.Windows.Forms.Button();
        this.resultLabel = new System.Windows.Forms.Label();
        this.progressBar1 = new System.Windows.Forms.ProgressBar();
        this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
        ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).
            BeginInit();
        this.SuspendLayout();

        // 
        // numericUpDown1
        // 
        this.numericUpDown1.set_Location(new System.Drawing.Point(16, 16));
        this.numericUpDown1.set_Maximum(new System.Decimal(
            new int[] { 91, 0, 0, 0 }));
        this.numericUpDown1.set_Minimum(new System.Decimal(
            new int[] { 1, 0, 0, 0 }));
        this.numericUpDown1.set_Name("numericUpDown1");
        this.numericUpDown1.set_Size(new System.Drawing.Size(80, 20));
        this.numericUpDown1.set_TabIndex(0);
        this.numericUpDown1.set_Value(new System.Decimal(
            new int[] { 1, 0, 0, 0 }));

        // 
        // startAsyncButton
        // 
        this.startAsyncButton.set_Location(new System.Drawing.Point(16, 72));
        this.startAsyncButton.set_Name("startAsyncButton");
        this.startAsyncButton.set_Size(new System.Drawing.Size(120, 23));
        this.startAsyncButton.set_TabIndex(1);
        this.startAsyncButton.set_Text("Start Async");
        this.startAsyncButton.add_Click(
            new System.EventHandler(this.startAsyncButton_Click));

        // 
        // cancelAsyncButton
        // 
        this.cancelAsyncButton.set_Enabled(false);
        this.cancelAsyncButton.set_Location(new System.Drawing.Point(153, 72));
        this.cancelAsyncButton.set_Name("cancelAsyncButton");
        this.cancelAsyncButton.set_Size(new System.Drawing.Size(119, 23));
        this.cancelAsyncButton.set_TabIndex(2);
        this.cancelAsyncButton.set_Text("Cancel Async");
        this.cancelAsyncButton.add_Click(
            new System.EventHandler(this.cancelAsyncButton_Click));

        // 
        // resultLabel
        // 
        this.resultLabel.set_BorderStyle(System.Windows.Forms.BorderStyle.Fixed3D);
        this.resultLabel.set_Location(new System.Drawing.Point(112, 16));
        this.resultLabel.set_Name("resultLabel");
        this.resultLabel.set_Size(new System.Drawing.Size(160, 23));
        this.resultLabel.set_TabIndex(3);
        this.resultLabel.set_Text("(no result)");
        this.resultLabel.set_TextAlign(System.Drawing.ContentAlignment.MiddleCenter);

        // 
        // progressBar1
        // 
        this.progressBar1.set_Location(new System.Drawing.Point(18, 48));
        this.progressBar1.set_Name("progressBar1");
        this.progressBar1.set_Size(new System.Drawing.Size(256, 8));
        this.progressBar1.set_Step(2);
        this.progressBar1.set_TabIndex(4);

        // 
        // backgroundWorker1
        // 
        this.backgroundWorker1.set_WorkerReportsProgress(true);
        this.backgroundWorker1.set_WorkerSupportsCancellation(true);

        // 
        // FibonacciForm
        // 
        this.set_ClientSize(new System.Drawing.Size(292, 118));
        this.get_Controls().Add(this.progressBar1);
        this.get_Controls().Add(this.resultLabel);
        this.get_Controls().Add(this.cancelAsyncButton);
        this.get_Controls().Add(this.startAsyncButton);
        this.get_Controls().Add(this.numericUpDown1);
        this.set_Name("FibonacciForm");
        this.set_Text("Fibonacci Calculator");
        ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).
            EndInit();
        this.ResumeLayout(false);
    } //InitializeComponent
    #endregion

    /** @attribute STAThread()
     */
    public static void main(String[] args)
    {
        Application.Run(new FibonacciForm());
    } //main
} //FibonacciForm
   
System.Object
   System.MarshalByRefObject
     System.ComponentModel.Component
      System.ComponentModel.BackgroundWorker
이 형식의 모든 public static(Visual Basic의 경우 Shared) 멤버는 스레드로부터 안전합니다. 인터페이스 멤버는 스레드로부터 안전하지 않습니다.

Windows 98, Windows 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition

.NET Framework에서 모든 플래폼의 모든 버전을 지원하지는 않습니다. 지원되는 버전의 목록은 시스템 요구 사항을 참조하십시오.

.NET Framework

2.0에서 지원
커뮤니티 콘텐츠   커뮤니티 콘텐츠란?
새 콘텐츠 추가 RSS  주석
Processing
© 2009 Microsoft Corporation. All rights reserved. 사용약관  |  상표  |  개인정보보호
Page view tracker