본문 바로가기

개발자국/WPF / Expression

[WPF] BackgroundWorker with UI Thread ProgressBar

 

progressbar 를 사용하려다 보니,

UI Thread 안에서 동작하는 함수 때문에,

progressbar는 UI님이 못된 함수놈을 기다리느라 여념이 없으시다.

 

Thread 하나로 모든걸 해결하려는 "간단유틸" 만드는 귀차니즘..

 

그리하여, BackgroundWorker 라는 곳으로 복잡한 함수를 보내버려

UI 님을 살려 드리고,

 

저 뒷편에서 UI 님에게 progress value를 주려고 시도하였다.

 

일단 소스부터 붙여 봅시다.

 

private BackgroundWorker backGroundWorker = new BackgroundWorker();
private delegate void UpdateValueDelegate(ProgressBar p, int v);
 
public MainWindow()
{
    InitializeComponent();
    backGroundWorker.DoWork += new DoWorkEventHandler(backGroundWorker_DoWork);
}
 
private void UpdateValue(ProgressBar p, int v)
{
    p.Value = v;
}
void backGroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 0; i <= 100; i++)
    {
        for (int j = 0; j < 10000000; j++)
        {
            // Do Timer
        }
        //progressBar1.Value = i;
 
        progressBar1.Dispatcher.BeginInvoke(
                                    new UpdateValueDelegate(UpdateValue), progressBar1, i);
    }
}
 
private void button1_Click(object sender, RoutedEventArgs e)
{
    backGroundWorker.RunWorkerAsync();
}

 

 

역시나 테스트용 코드라 복잡하기 짝이 없군..

 

일단은 BackgroundWorker를 하나 선언해 주고,

 

Window Creation 할 때,

backGroundWorker.Dowork += (Tab키 따닥~)

 

해서 Handler 등록을 한다.

Handler에는 아까 UI님을 죽게 하였던 문제의 함수를 넣어준다. (예제에는 엄청난 루프)

 

button1을 클릭하면 backGroundWorker.RunWorkerAsync(); 함수를 실행하고,

 

DoWork에 등록된 Handler 가 실행이 된다.

새로운 Thread의 탄생으로 UI님은 여유로운 시간을 보내실 수 있다.

 

단!!

아무리 여유로운 시간을 보내시고 있더라도,

다른 Thread 놈이 UI님의 자식을 건드리면 버럭! 화를 내신다.

 

이것을 위하여 progressBar1.Value = i; 대신

progressBar1.Dispatcher.BeginInvoke 라는 명령어를 써서 Delegate를 실행시키는 방법을 쓴다.

 

이 방법은 다른 Thread 놈이 UI Thread 님에게 접근할 수 있는 방법 되겠다.