기타

WPF 따라하기 - BackgroundWorker

카멜레온개발자 2022. 7. 9. 10:59

https://youtu.be/KfY6DqWtcqs?list=PLxU-iZCqT52Cmj47aKB1T-SxI33YL7rYS

위의 영상에 나오는 코드 따라해봄

 

UI가 XML로 되어 있는 것 빼고는 아직까지 C#과 동일

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Wpf5
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        BackgroundWorker worker;

        int sum = 0;

        public MainWindow()
        {
            InitializeComponent();
        }

        protected override void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);

            //Progress Changed 이벤트 발생 여부
            //작업취소 가능 여부
            worker = new BackgroundWorker()
            {
                WorkerReportsProgress = true,
                WorkerSupportsCancellation = true,
            };

            worker.DoWork += Worker_DoWork;

            worker.ProgressChanged += Worker_ProgressChanged;

            worker.RunWorkerCompleted += Worker_RunWorkerCompleted;

            MessageBox.Show("초기화");
        }

        private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled) MessageBox.Show("작업 취소");
            else if (e.Error != null) MessageBox.Show("에러 발생..." + e.Error);
            else
            {
                lblSum.Content = ((int)e.Result).ToString();
                MessageBox.Show("작업완료");
            }
        }

        private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar.Value = e.ProgressPercentage;
        }

        private void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            int count = (int)e.Argument;

            for(int i=0; i<=count; ++i)
            {
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
                else
                {
                    Thread.Sleep(1000);
                    Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
                        (ThreadStart)delegate ()
                        {
                            if(i%2 == 0)
                            {
                                sum += i;
                                e.Result = sum;
                                lstNumber.Items.Add(i);
                            }
                        });

                    worker.ReportProgress(i);
                }
            }

        }

        private void btnStart_Click(object sender, RoutedEventArgs e)
        {
            if(worker.IsBusy == true)
            {
                MessageBox.Show("작업이 진행중입니다");
            }
            else
            {
                int num = 0;
                if (int.TryParse(txtNumber.Text, out num) == false)
                {
                    MessageBox.Show("숫자를 입력하세요");
                    return;
                }

                progressBar.Maximum = num;
                lstNumber.Items.Clear();
                worker.RunWorkerAsync(num);
            }
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            worker.CancelAsync();
        }
    }
}