BackgroundWorker 클래스
BackgroundWorker 클래스
별도의 스레드에서 작업을 실행합니다.
별도의 스레드에서 작업을 실행합니다.
System.Object
System.MarshalByRefObject
System.ComponentModel.Component
System.ComponentModel.BackgroundWorker
네임스페이스: System.ComponentModel
어셈블리: System(System.dll)
System.MarshalByRefObject
System.ComponentModel.Component
System.ComponentModel.BackgroundWorker
어셈블리: System(System.dll)
표시: 이름 설명 CancellationPending 응용 프로그램에서 백그라운드 작업의 취소를 요청했는지 여부를 나타내는 값을 가져옵니다. CanRaiseEvents 구성 요소가 이벤트를 발생시킬 수 있는지 여부를 나타내는 값을 가져옵니다.(Component에서 상속됨) Container Component 가 포함된 IContainer를 가져옵니다. (Component에서 상속됨) DesignMode Component 가 현재 디자인 모드인지 여부를 나타내는 값을 가져옵니다.(Component에서 상속됨) Events 이 Component에 연결된 이벤트 처리기의 목록을 가져옵니다. (Component에서 상속됨) IsBusy BackgroundWorker 가 비동기 작업을 실행하고 있는지 여부를 나타내는 값을 가져옵니다. Site Component 의 ISite를 가져오거나 설정합니다. (Component에서 상속됨) WorkerReportsProgress BackgroundWorker 가 진행률 업데이트를 보고할 수 있는지 여부를 나타내는 값을 가져오거나 설정합니다. WorkerSupportsCancellation BackgroundWorker 가 비동기 취소를 지원하는지 여부를 나타내는 값을 가져오거나 설정합니다.
위쪽
이름 | 설명 | |
---|---|---|
CancellationPending | 응용 프로그램에서 백그라운드 작업의 취소를 요청했는지 여부를 나타내는 값을 가져옵니다. | |
CanRaiseEvents | 구성 요소가 이벤트를 발생시킬 수 있는지 여부를 나타내는 값을 가져옵니다.(Component에서 상속됨) | |
Container | Component 가 포함된 IContainer를 가져옵니다. (Component에서 상속됨) | |
DesignMode | Component 가 현재 디자인 모드인지 여부를 나타내는 값을 가져옵니다.(Component에서 상속됨) | |
Events | 이 Component에 연결된 이벤트 처리기의 목록을 가져옵니다. (Component에서 상속됨) | |
IsBusy | BackgroundWorker 가 비동기 작업을 실행하고 있는지 여부를 나타내는 값을 가져옵니다. | |
Site | Component 의 ISite를 가져오거나 설정합니다. (Component에서 상속됨) | |
WorkerReportsProgress | BackgroundWorker 가 진행률 업데이트를 보고할 수 있는지 여부를 나타내는 값을 가져오거나 설정합니다. | |
WorkerSupportsCancellation | BackgroundWorker 가 비동기 취소를 지원하는지 여부를 나타내는 값을 가져오거나 설정합니다. |
표시: 이름 설명 CancelAsync 보류 중인 백그라운드 작업의 취소를 요청합니다. CreateObjRef 원격 개체와 통신하는 데 사용되는 프록시 생성에 필요한 모든 관련 정보가 들어 있는 개체를 만듭니다. (MarshalByRefObject에서 상속됨) Dispose() Component 에서 사용하는 모든 리소스를 해제합니다. (Component에서 상속됨) Dispose(Boolean) Component 에서 사용하는 관리되지 않는 리소스를 해제하고, 관리되는 리소스를 선택적으로 해제할 수 있습니다. (Component에서 상속됨) Equals(Object) 지정한 개체가 현재 개체와 같은지 여부를 확인합니다. (Object에서 상속됨)Finalize 가비지 수집에 의해 Component가 회수되기 전에 관리되지 않는 리소스를 해제하고 기타 정리 작업을 수행합니다. (Component에서 상속됨) GetHashCode 기본 해시 함수로 작동합니다. (Object에서 상속됨) GetLifetimeService 이 인스턴스의 수명 정책을 제어하는 현재의 수명 서비스 개체를 검색합니다.(MarshalByRefObject에서 상속됨) GetService Component 또는 해당 Container에서 제공하는 서비스를 나타내는 개체를 반환합니다. (Component에서 상속됨) GetType 현재 인스턴스의 Type을 가져옵니다. (Object에서 상속됨) InitializeLifetimeService 이 인스턴스의 수명 정책을 제어하기 위한 수명 서비스 개체를 가져옵니다.(MarshalByRefObject에서 상속됨) MemberwiseClone() 현재 Object의 단순 복사본을 만듭니다. (Object에서 상속됨) MemberwiseClone(Boolean) 현재 MarshalByRefObject 개체의 단순 복사본을 만듭니다. (MarshalByRefObject에서 상속됨) OnDoWork DoWork 이벤트를 발생시킵니다. OnProgressChanged ProgressChanged 이벤트를 발생시킵니다. OnRunWorkerCompleted RunWorkerCompleted 이벤트를 발생시킵니다. ReportProgress(Int32) ProgressChanged 이벤트를 발생시킵니다. ReportProgress(Int32, Object) ProgressChanged 이벤트를 발생시킵니다. RunWorkerAsync() 백그라운드 작업의 실행을 시작합니다. RunWorkerAsync(Object) 백그라운드 작업의 실행을 시작합니다. ToString Component 의 이름이 포함된 String을 반환합니다. 이 메서드는 재정의할 수 없습니다. (Component에서 상속됨)
위쪽
이름 | 설명 | |
---|---|---|
CancelAsync | 보류 중인 백그라운드 작업의 취소를 요청합니다. | |
CreateObjRef | 원격 개체와 통신하는 데 사용되는 프록시 생성에 필요한 모든 관련 정보가 들어 있는 개체를 만듭니다. (MarshalByRefObject에서 상속됨) | |
Dispose() | Component 에서 사용하는 모든 리소스를 해제합니다. (Component에서 상속됨) | |
Dispose(Boolean) | Component 에서 사용하는 관리되지 않는 리소스를 해제하고, 관리되는 리소스를 선택적으로 해제할 수 있습니다. (Component에서 상속됨) | |
Equals(Object) | ||
Finalize | 가비지 수집에 의해 Component가 회수되기 전에 관리되지 않는 리소스를 해제하고 기타 정리 작업을 수행합니다. (Component에서 상속됨) | |
GetHashCode | 기본 해시 함수로 작동합니다. (Object에서 상속됨) | |
GetLifetimeService | 이 인스턴스의 수명 정책을 제어하는 현재의 수명 서비스 개체를 검색합니다.(MarshalByRefObject에서 상속됨) | |
GetService | Component 또는 해당 Container에서 제공하는 서비스를 나타내는 개체를 반환합니다. (Component에서 상속됨) | |
GetType | 현재 인스턴스의 Type을 가져옵니다. (Object에서 상속됨) | |
InitializeLifetimeService | 이 인스턴스의 수명 정책을 제어하기 위한 수명 서비스 개체를 가져옵니다.(MarshalByRefObject에서 상속됨) | |
MemberwiseClone() | 현재 Object의 단순 복사본을 만듭니다. (Object에서 상속됨) | |
MemberwiseClone(Boolean) | 현재 MarshalByRefObject 개체의 단순 복사본을 만듭니다. (MarshalByRefObject에서 상속됨) | |
OnDoWork | DoWork 이벤트를 발생시킵니다. | |
OnProgressChanged | ProgressChanged 이벤트를 발생시킵니다. | |
OnRunWorkerCompleted | RunWorkerCompleted 이벤트를 발생시킵니다. | |
ReportProgress(Int32) | ProgressChanged 이벤트를 발생시킵니다. | |
ReportProgress(Int32, Object) | ProgressChanged 이벤트를 발생시킵니다. | |
RunWorkerAsync() | 백그라운드 작업의 실행을 시작합니다. | |
RunWorkerAsync(Object) | 백그라운드 작업의 실행을 시작합니다. | |
ToString | Component 의 이름이 포함된 String을 반환합니다. 이 메서드는 재정의할 수 없습니다. (Component에서 상속됨) |
표시: 이름 설명 Disposed Dispose 메서드를 호출하여 구성 요소가 삭제되는 경우 발생합니다. (Component에서 상속됨) DoWork RunWorkerAsync 가 호출될 때 발생합니다. ProgressChanged ReportProgress 가 호출될 때 발생합니다. RunWorkerCompleted 백그라운드 작업이 완료되거나 취소되거나 예외를 발생시켰을 때 발생합니다.
위쪽
이름 | 설명 | |
---|---|---|
Disposed | Dispose 메서드를 호출하여 구성 요소가 삭제되는 경우 발생합니다. (Component에서 상속됨) | |
DoWork | RunWorkerAsync 가 호출될 때 발생합니다. | |
ProgressChanged | ReportProgress 가 호출될 때 발생합니다. | |
RunWorkerCompleted | 백그라운드 작업이 완료되거나 취소되거나 예외를 발생시켰을 때 발생합니다. |
BackgroundWorker 클래스를 사용하면 별도의 전용 스레드에서 작업을 실행할 수 있습니다. 다운로드 및 데이터베이스 트랜잭션과 같은 시간이 많이 걸리는 작업이 실행되는 동안에는 UI(사용자 인터페이스)가 응답을 중지한 것처럼 보일 수 있습니다. UI의 응답 속도를 높이려 하고 이러한 작업과 관련된 지연 시간이 길어지는 경우 BackgroundWorker 클래스는 간편한 해결책을 제공합니다.
백그라운드에서 시간이 많이 걸리는 작업을 실행하려면 BackgroundWorker를 만든 다음 작업의 진행률을 보고하고 작업이 끝날 때 알리는 이벤트를 수신합니다. 프로그래밍 방식으로 BackgroundWorker를 만들거나 이 개체를 도구 상자의 구성 요소 탭에서 폼으로 끌어 올 수 있습니다. Windows Forms 디자이너에서 BackgroundWorker를 만들면 이 개체가 구성 요소 트레이에 나타나고 해당 속성이 속성 창에 표시됩니다.
백그라운드 작업에 대해 설정하려면 DoWork 이벤트에 대한 이벤트 처리기를 추가해야 합니다. 완료하는 데 시간이 많이 걸리는 작업을 이 이벤트 처리기로 호출합니다. 작업을 시작하려면 RunWorkerAsync를 호출합니다. 진행률 업데이트 알림을 받으려면ProgressChanged 이벤트를 처리합니다. 작업이 완료될 때 알림을 받으려면 RunWorkerCompleted 이벤트를 처리합니다.
참고 DoWork 이벤트 처리기에서 사용자 인터페이스 개체를 조작하지 않도록 주의해야 합니다. 대신 ProgressChanged 및RunWorkerCompleted 이벤트를 통해 사용자 인터페이스와 통신합니다.
BackgroundWorker 이벤트는 AppDomain 경계를 넘어 마샬링되지 않습니다. BackgroundWorker 구성 요소를 사용하여 둘 이상의AppDomain에서 다중 스레드 작업을 수행하지 마십시오.
백그라운드 작업에 매개 변수가 필요하면 매개 변수를 사용하여 RunWorkerAsync를 호출합니다. DoWork 이벤트 처리기 안에 있는DoWorkEventArgs.Argument 속성에서 매개 변수를 추출할 수 있습니다.
BackgroundWorker 에 대한 자세한 내용은 방법: 백그라운드에서 작업 실행을 참조하십시오.
참고 이 형식 또는 멤버에 적용되는 HostProtectionAttribute 특성의 Resources 속성 값은 SharedState입니다. HostProtectionAttribute는 대개 아이콘을 두 번 클릭하거나, 명령을 입력하거나, 브라우저에서 URL을 입력하여 시작되는 데스크톱 응용 프로그램에 영향을 미치지 않습니다. 자세한 내용은 HostProtectionAttribute 클래스 또는 SQL Server 프로그래밍 및 호스트 보호 특성을 참조하십시오.
BackgroundWorker 클래스를 사용하면 별도의 전용 스레드에서 작업을 실행할 수 있습니다. 다운로드 및 데이터베이스 트랜잭션과 같은 시간이 많이 걸리는 작업이 실행되는 동안에는 UI(사용자 인터페이스)가 응답을 중지한 것처럼 보일 수 있습니다. UI의 응답 속도를 높이려 하고 이러한 작업과 관련된 지연 시간이 길어지는 경우 BackgroundWorker 클래스는 간편한 해결책을 제공합니다.
백그라운드에서 시간이 많이 걸리는 작업을 실행하려면 BackgroundWorker를 만든 다음 작업의 진행률을 보고하고 작업이 끝날 때 알리는 이벤트를 수신합니다. 프로그래밍 방식으로 BackgroundWorker를 만들거나 이 개체를 도구 상자의 구성 요소 탭에서 폼으로 끌어 올 수 있습니다. Windows Forms 디자이너에서 BackgroundWorker를 만들면 이 개체가 구성 요소 트레이에 나타나고 해당 속성이 속성 창에 표시됩니다.
백그라운드 작업에 대해 설정하려면 DoWork 이벤트에 대한 이벤트 처리기를 추가해야 합니다. 완료하는 데 시간이 많이 걸리는 작업을 이 이벤트 처리기로 호출합니다. 작업을 시작하려면 RunWorkerAsync를 호출합니다. 진행률 업데이트 알림을 받으려면ProgressChanged 이벤트를 처리합니다. 작업이 완료될 때 알림을 받으려면 RunWorkerCompleted 이벤트를 처리합니다.
참고 |
---|
DoWork 이벤트 처리기에서 사용자 인터페이스 개체를 조작하지 않도록 주의해야 합니다. 대신 ProgressChanged 및RunWorkerCompleted 이벤트를 통해 사용자 인터페이스와 통신합니다. BackgroundWorker 이벤트는 AppDomain 경계를 넘어 마샬링되지 않습니다. BackgroundWorker 구성 요소를 사용하여 둘 이상의AppDomain에서 다중 스레드 작업을 수행하지 마십시오. |
백그라운드 작업에 매개 변수가 필요하면 매개 변수를 사용하여 RunWorkerAsync를 호출합니다. DoWork 이벤트 처리기 안에 있는DoWorkEventArgs.Argument 속성에서 매개 변수를 추출할 수 있습니다.
BackgroundWorker 에 대한 자세한 내용은 방법: 백그라운드에서 작업 실행을 참조하십시오.
참고 |
---|
이 형식 또는 멤버에 적용되는 HostProtectionAttribute 특성의 Resources 속성 값은 SharedState입니다. HostProtectionAttribute는 대개 아이콘을 두 번 클릭하거나, 명령을 입력하거나, 브라우저에서 URL을 입력하여 시작되는 데스크톱 응용 프로그램에 영향을 미치지 않습니다. 자세한 내용은 HostProtectionAttribute 클래스 또는 SQL Server 프로그래밍 및 호스트 보호 특성을 참조하십시오. |
다음 코드 예제에서는 BackgroundWorker 클래스의 기본 사항을 통해 시간이 많이 걸리는 작업을 비동기적으로 실행하는 방법을 보여 줍니다. 다음 그림에서는 출력의 예제를 보여 줍니다.
이 코드를 시도하려면 Windows Forms 응용 프로그램을 만듭니다. resultLabel이라는 이름의 Label 컨트롤을 추가하고startAsyncButton 및 cancelAsyncButton이라는 이름의 두 개의 Button 컨트롤을 추가합니다. 두 단추에 대한 Click 이벤트 처리기를 만듭니다. 도구 상자의 구성 요소 탭에서 backgroundWorker1이라는 이름의 BackgroundWorker 구성 요소를 추가합니다.BackgroundWorker 에 대한 DoWork, ProgressChanged 및 RunWorkerCompleted 이벤트 처리기를 만듭니다. 폼에 대한 코드에서 기존 코드를 다음 코드로 바꿉니다.
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace BackgroundWorkerSimple
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
}
private void startAsyncButton_Click(object sender, EventArgs e)
{
if (backgroundWorker1.IsBusy != true)
{
// Start the asynchronous operation.
backgroundWorker1.RunWorkerAsync();
}
}
private void cancelAsyncButton_Click(object sender, EventArgs e)
{
if (backgroundWorker1.WorkerSupportsCancellation == true)
{
// Cancel the asynchronous operation.
backgroundWorker1.CancelAsync();
}
}
// This event handler is where the time-consuming work is done.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 1; i <= 10; i++)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
// Perform a time consuming operation and report progress.
System.Threading.Thread.Sleep(500);
worker.ReportProgress(i * 10);
}
}
}
// This event handler updates the progress.
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
resultLabel.Text = (e.ProgressPercentage.ToString() + "%");
}
// This event handler deals with the results of the background operation.
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled == true)
{
resultLabel.Text = "Canceled!";
}
else if (e.Error != null)
{
resultLabel.Text = "Error: " + e.Error.Message;
}
else
{
resultLabel.Text = "Done!";
}
}
}
}
다음 코드 예제에서는 BackgroundWorker 클래스를 사용하여 시간이 많이 걸리는 작업을 비동기적으로 실행하는 방법을 보여 줍니다.다음 그림에서는 출력의 예제를 보여 줍니다.
작업에서는 선택된 피바노치(Fibonacci) 수를 계산하고 계산이 진행됨에 따라 진행률 업데이트를 보고하며 보류 중인 계산을 취소할 수 있도록 합니다.
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();
InitializeBackgroundWorker();
}
// Set up the BackgroundWorker object by
// attaching event handlers.
private void InitializeBackgroundWorker()
{
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());
}
}
}
다음 코드 예제에서는 BackgroundWorker 클래스의 기본 사항을 통해 시간이 많이 걸리는 작업을 비동기적으로 실행하는 방법을 보여 줍니다. 다음 그림에서는 출력의 예제를 보여 줍니다.
이 코드를 시도하려면 Windows Forms 응용 프로그램을 만듭니다. resultLabel이라는 이름의 Label 컨트롤을 추가하고startAsyncButton 및 cancelAsyncButton이라는 이름의 두 개의 Button 컨트롤을 추가합니다. 두 단추에 대한 Click 이벤트 처리기를 만듭니다. 도구 상자의 구성 요소 탭에서 backgroundWorker1이라는 이름의 BackgroundWorker 구성 요소를 추가합니다.BackgroundWorker 에 대한 DoWork, ProgressChanged 및 RunWorkerCompleted 이벤트 처리기를 만듭니다. 폼에 대한 코드에서 기존 코드를 다음 코드로 바꿉니다.
using System; using System.ComponentModel; using System.Windows.Forms; namespace BackgroundWorkerSimple { public partial class Form1 : Form { public Form1() { InitializeComponent(); backgroundWorker1.WorkerReportsProgress = true; backgroundWorker1.WorkerSupportsCancellation = true; } private void startAsyncButton_Click(object sender, EventArgs e) { if (backgroundWorker1.IsBusy != true) { // Start the asynchronous operation. backgroundWorker1.RunWorkerAsync(); } } private void cancelAsyncButton_Click(object sender, EventArgs e) { if (backgroundWorker1.WorkerSupportsCancellation == true) { // Cancel the asynchronous operation. backgroundWorker1.CancelAsync(); } } // This event handler is where the time-consuming work is done. private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; for (int i = 1; i <= 10; i++) { if (worker.CancellationPending == true) { e.Cancel = true; break; } else { // Perform a time consuming operation and report progress. System.Threading.Thread.Sleep(500); worker.ReportProgress(i * 10); } } } // This event handler updates the progress. private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { resultLabel.Text = (e.ProgressPercentage.ToString() + "%"); } // This event handler deals with the results of the background operation. private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled == true) { resultLabel.Text = "Canceled!"; } else if (e.Error != null) { resultLabel.Text = "Error: " + e.Error.Message; } else { resultLabel.Text = "Done!"; } } } }
다음 코드 예제에서는 BackgroundWorker 클래스를 사용하여 시간이 많이 걸리는 작업을 비동기적으로 실행하는 방법을 보여 줍니다.다음 그림에서는 출력의 예제를 보여 줍니다.
작업에서는 선택된 피바노치(Fibonacci) 수를 계산하고 계산이 진행됨에 따라 진행률 업데이트를 보고하며 보류 중인 계산을 취소할 수 있도록 합니다.
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(); InitializeBackgroundWorker(); } // Set up the BackgroundWorker object by // attaching event handlers. private void InitializeBackgroundWorker() { 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()); } } }
.NET Framework
.NET Framework Client Profile
4, 3.5 SP1에서 지원
Windows Phone 앱용 .NET
Windows Phone 8, Silverlight 8.1에서 지원
Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008(서버 코어 역할은 지원되지 않음), Windows Server 2008 R2(서버 코어 역할은 SP1 이상에서 지원, Itanium은 지원되지 않음)
.NET Framework에서 모든 플랫폼의 전체 버전을 지원하지는 않습니다. 지원되는 버전의 목록을 보려면 .NET Framework 시스템 요구 사항을 참조하십시오.
Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008(서버 코어 역할은 지원되지 않음), Windows Server 2008 R2(서버 코어 역할은 SP1 이상에서 지원, Itanium은 지원되지 않음)
.NET Framework에서 모든 플랫폼의 전체 버전을 지원하지는 않습니다. 지원되는 버전의 목록을 보려면 .NET Framework 시스템 요구 사항을 참조하십시오.참조
기타 리소스
'Programming > WinForm' 카테고리의 다른 글
[펌] C# WinForm "인증서 저장소에서 매니페스트 서명 인증서를 찾을 수 없습니다." (0) | 2019.01.25 |
---|---|
Load a Cursor from a Resources in C# (0) | 2014.11.07 |
BackGroundWorker 예제 ( Thread 대용품 ) (0) | 2014.11.04 |
쓰레드 선호도 (Thread Affinity) (0) | 2014.11.03 |
Cursors in C# (0) | 2014.11.03 |