우선, 생성자를 보면은 myWorker 필드를 설정하는 내용이 나옵니다.
myWorker.DoWork += new DoWorkEventHandler(myWorker_DoWork);
myWorker.WorkerReportsProgress = true;
myWorker.ProgressChanged +=
new ProgressChangedEventHandler(myWorker_ProgressChanged);
myWorker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(myWorker_RunWorkerCompleted);
DoWork 이벤트, ProgressChanged 이벤트, RunWorkerCompleted 이벤트에 적절한
이벤트 핸들러를 설정했습니다.
그런데, myWorker.WorkerReportsProgress = true; 라는 문장이 있죠.
이렇게 WorkerReportsProgress 프로퍼티를 true 값으로 설정해야,
ProgressChanged 이벤트가 일어나게 됩니다.
DoWork 이벤트 핸들러를 살펴볼까요?
void myWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i <= 5; ++i)
{
Thread.Sleep(1000);
myWorker.ReportProgress(i);
}
Thread.Sleep(1000);
}
보시다시피, for 문 안에서 1초 간격으로 ReportProgress() 메소드를 호출하는데,
이 메소드를 호출하면 ProgressChanged 이벤트가 일어나므로,
백그라운드 작업 도중에 사용자 인터페이스를 변경하는 작업을 수행할 수 있게 됩니다.
void myWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.label1.Text = "No. " + e.ProgressPercentage.ToString();
}
DoWork 이벤트 핸들러에서 ReportProgress() 메소드 호출할 때마다 일어나는
ProgressChanged 이벤트 핸들러는 단순히 레이블의 텍스트를 변경합니다.
원한다면, 다른 효과를 적용할 수도 있습니다. 예를 들면, 레이블의 배경 색상을 변경할 수도 있죠.
이제, DoWork 이벤트 핸들러 작업이 끝나면,
RunWorkerCompleted 이벤트가 일어나므로, 이 이벤트에 대한 이벤트 핸들러가 실행됩니다.
void myWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.label1.Text = "Completed!";
}
최종적으로, 레이블의 텍스트를 변경하는 것 밖에 없습니다.
아래에는 버튼을 클릭 이벤트 핸들러가 나와 있는데,
IsBusy 프로퍼티를 검사하는 코드가 나와 있습니다.
private void button1_Click(object sender, EventArgs e)
{
if (myWorker.IsBusy != true)
myWorker.RunWorkerAsync();
}
이렇게 해야 하는 이유는,
버튼의 클릭 이벤트 핸들러는 최소 6초가 소요되는 작업을 수행하는데,
두 번 이상 버튼을 클릭할 수도 있게 됩니다.
만일, 두 번 이상 버튼을 클릭하면 이미 백그라운드에서 작업이 진행되고 있는데,
또다른 작업을 요청하게 되므로 에러가 발생합니다.
따라서, IsBusy 프로퍼티를 검사하여, 백그라운드 작업이 실행 중인지 검사하여,
작업이 실행된다면, 아무일도 하지 않도록 했습니다.
잘 참고하시면, 굳이 타이머를 이용하지 않고도,
훨씬 안정적인 다중 쓰레드 프로그램을 만들 수 있을 겁니다.
잘 이해 안되는 게 있으면 쪽지 주세요.
그럼. 수고하세요~
http://msdn.microsoft.com/ko-kr/library/48cfdff6(VS.80).aspx