VB.NET 2008/VB - 컨트롤

컨트롤 - BackgroundWorker 구성 요소

본클라쓰 2011. 4. 25. 09:53

 

일반적으로 수행하는 많은 작업 중에는 실행하는 데 오랜 시간이 걸리는 경우가 많다. 예를 들면 다음과 같다.

 

- 이미지 다운로드

- 웹 서비스 호출

- 파일 다운로드 및 업로드

- 복잡한 로컬 계산

- 데이터베이스 트랜잭션

- 로컬 디스크 액세스

 

 이러한 작업을 실행하는 동안에는 사용자 인터페이스가 응답하지 않을 수 있다. 이러한 작업으로 인한 지연이 길어져 UI가 응답하지 않는 경우 BackgroundWorker 구성 요소를 사용하여 이러한 문제를 쉽게 해결할 수 있다.

 

 

BackgroundWorker 구성 요소를 사용하면 응용 프로그램의 주 UI 스레드와 다른 스레드에서 시간이 많이 소모되는 작업을 "백그라운드"에서 비동기적으로 실행할 수 있다. BackgroundWorker를 사용하려면 백그라운드에서 실행할 시간이 많이 소모되는 작업자 메서드를 지정한 다음 RunWorkerAsyc 메서드를 호출한다. 작업자 메서드가 비동기적으로 실행되는 동안에도 호출 스레드는 계속 정상적으로 실행된다. 메서드가 완료되면 BackgroundWorker는 RunWorkerCompleted 이벤트를 발생시켜 호출 스레드에 알린다. 이 벤트에는 선택적 작업 결과를 포함시킬 수 있다.

 

도구 상자의 구성 요소 탭에서 BackgroundWorker 구성 요소를 사용할 수 있다. 폼에 BackgroundWorker를 추가하려면 BackgroundWorker 구성 요소를 폼으로 끈다. 그러면 구성 요소 트레이에 해당 구성 요소가 나타나며 속성 창에 해당 속성이 나타난다.

 

비동기 작업을 시작하려면 RunWorkerAsync 메서드를 사용한다. RunWorkerAsync 는 작업자 메서드에 인수를 전달하는 데 사용할 수 있는 선택적 Object 매개 변수를 사용한다. BackgroundWorker 클래스는 DoWork 이벤트를 노출하며 작업자 스레드는 DoWork 이벤트 처리기를 통해 이 이벤트에 연결된다.

 

DoWork 이벤트 처리기는 Argument 속성을 포함하는 DoWorkEventArgs 매개 변수를 사용한다. 이 속성은 RunWorkerAsync에서 매개 변수를 받으며 DoWork 이벤트 처리기에서 호출될 작업자 메서드에 전달될 수 있다.

 

 

' 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

 

 

다음은 BackgroundWorker 구성 요소의 비동기 이벤트에 대한 이벤트 처리기를 추가해 진행바를 나타내는 예제이다.

 

' 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 IntegerByVal 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 IntegerCSng(n) / CSng(numberToCompute) * 100


        If percentComplete > highestPercentageReached Then
            highestPercentageReached = percentComplete
            worker.ReportProgress(percentComplete)
        End If

    End If

    Return result

End Function

 

Dowork 이벤트 처리기에서 Computefibonacci 메서드 호출을 추가한다. DoWorkEventArgs의 Arguments 속성에서 ComputeFibonacci에 대한 첫 번째 매개 변수를 가져온다. BackgroundWorker 및 DoWorkEventArgs 매개 변수는 나중에 진행률 보고 및 취소 지원에 사용된다.

 

시간이 오래 걸리는 비동기 작업의 경우 사용자에게 진행률을 보고하여 사용자가 작업을 취소할 수 있도록 하는 것이 좋다. BackgroundWorker 클래스는 백그라운드 작업이 수행될 때 진행률을 게시할 수 있는 이벤트를 제공한다. 또한 해당 클래스는 작업자 코드가 CancelAsync에 대한 호출을 감지하여 스스로 중지할 수 있게 하는 플래그를 제공한다.

 

BackgroundWorker의 WorkerReportsProgress WorkerSupportCancellation 속성을 true로 설정한다.

 

 

그리고 폼에 두 개의 변수를 선언한다. 이러한 변수는 진행률을 추적하는 데 사용된다.

 

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

 

 

ProgressChanged 이벤트에 대한 이벤트 처리기를 추가한다. ProgressChanged 이벤트 처리기에서 Progressbar1를 ProgressChangedEventArgs 매개 변수의 ProgressPercentage 속성으로 업데이트한다.

 

' This event handler updates the progress bar.
Private Sub backgroundWorker1_ProgressChanged( ByVal sender As Object, _

ByVal e As rogressChangedEventArgs) Handles backgroundWorker1.ProgressChanged

    Me.progressBar1.Value = e.ProgressPercentage

End Sub

 

 

취소 버튼에 대한 지원을 구현할 때는 취소 버튼의 Click 이벤트 처리기에 비동기 작업을 취소하는 코드를 추가한다.

 

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