티스토리 뷰

프로그래밍/.NetFramework

BackgroundWorker 사용법

쇠주는참이슬 2014. 2. 10. 11:13

 

 
BackgroundWorker 사용법
예제를 맨날 Winform 으로만 하다보니 지겨워서..
이번에는 WPF를 가지고 테스트!!

BackgroundWorker 를 사용하는 경우는
어떤 특정한 작업이 시간이 오래 걸리는 경우 사용자에게 현재 진행상태를 보여줘야 하는 상황이 있다.
이런 경우 BackgroundWorker를 사용하면 백그라운드에서 비동기로 실행되는 동안 호출되는 스레드들이 정상적으로 작동을 한다.

아래와 같이 코드를 작성하고 실행을 딱!!! 하면!!
 /// 
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// 
    public partial class MainWindow : Window
    {
        // BackgroundWorker 인스턴스 객체 생성
        BackgroundWorker worker = new BackgroundWorker();

        public MainWindow()
        {
            InitializeComponent(); 
            
            worker.DoWork += worker_DoWork;                                                // 실제 작업이 이루어지는 이벤트
            worker.RunWorkerCompleted += worker_RunWorkerCompleted;    // 작업이 종료된 후에 발생하는 이벤트 
            worker.WorkerReportsProgress = true;
            worker.WorkerSupportsCancellation = true; 
        }

       
        /// 
        ///  작업완료 후 발생하는 이벤트
        /// 
        /// 
        /// 
        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show("Error" + e.Error.Message);
            }
            else if (e.Cancelled == true)
            {
                MessageBox.Show("취소완료");
            }
            else
            {
                MessageBox.Show("작업완료");
            }
        }

        /// 
        /// 실제 비동기 작업이 이루어지는 메서드
        /// 
        /// 
        /// 
        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            // btnExecute_Click 에서 넘겨준 argument를 받는다.
            int arg = (int)e.Argument;
            

            for (int i = 0; i < arg; i++)
            {
                // 작업상태가 취소면 작업을 종료한다.
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                }

                // 아니면 계속 진행
                if (!e.Cancel)
                {
                    progressBar1.Value = i; 
                }
            } 
        }


        /// 
        /// 작업시작
        /// 
        /// 
        /// 
        private void btnExecute_Click(object sender, RoutedEventArgs e)
        {
            int arg = 100000;
            progressBar1.Maximum = arg;

            //BackgroundWorker 작업시작 worker_DoWork 메서드 호출
            worker.RunWorkerAsync(arg);
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            // BackgroundWorker 작업취소
            worker.CancelAsync();
        }
    }
"다른 스레드가 이 개체를 사용하고 있어 호출한 스레드가 해당 개체에 액세스할 수 없습니다."
????????????????? 
?????????????????
?????????????????

이런 젠장.
Winform 은 그냥 위에 소스대로 실행해도 잘~~ 작동하지만!!
Winform 과는 달리 WPF 에서는 아래와같이 Dowork 이벤트에 내용을 변경해줘야한다. 
  /// 
        /// 실제 비동기 작업이 이루어지는 메서드
        /// 
        /// 
        /// 
        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            // btnExecute_Click 에서 넘겨준 argument를 받는다.
            int arg = (int)e.Argument;
            

            for (int i = 0; i < arg; i++)
            {
                // 작업상태가 취소면 작업을 종료한다.
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                }

                // 아니면 계속 진행
                if (!e.Cancel)
                { 
                    Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate
                    {
                        progressBar1.Value = i;
                    })); 
                }
            } 
        }
변경하고 다시 실행하면 잘~~ 된다. WPF, BackgrounWorker, 백그라운드워커, Thread


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함