블로그 이미지
따시쿵

calendar

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 31

Notice

2015. 3. 2. 17:16 C#

프로그램 설명


BackgroundWorker 클래스를 이용한 프로그램을 만들어 봤습니다.


두 가지 방법으로 만들었는데,

첫번째 방법은 도구 상자에서 Background 컴포넌트를 디자인 화면에 드래그하는 방법과 두번째는 스크립트로 직접 타이핑을 하는 방법으로 개발했습니다.


첫번째 프로그램에 thread id 를 Debug 시에 출력을 해서 어떤 method 가 ui thread와 다르게 운영되는지 확인 해 보았습니다. 예상한대로 DoWork method 가 ui thread와 다르네요.


new Thread와 비교를 해보면 화면 출력을 편리하게 할 수 있고, 진행 상황을 확인해야 하는 프로그램에 적용하면 편리하게 사용이 가능할 듯 합니다.

 

실행 후





프로그램 작성


1. 첫번째 프로그램


        public MainForm()
        {
            InitializeComponent();

            Debug.WriteLine("MainForm() thread id : {0}", Thread.CurrentThread.ManagedThreadId);
        }

        #region start buton click method
        private void btnStart_Click(object sender, EventArgs e)
        {
            if (backgroundWorker1.IsBusy)
                label2.Text = "Busy processing, please waiting!!!!";
            else
                backgroundWorker1.RunWorkerAsync();

            Debug.WriteLine("btnStart_Click() thread id : {0}", Thread.CurrentThread.ManagedThreadId);
        }
        #endregion
             
        #region cancel buton click method
        private void btnCalcel_Click(object sender, EventArgs e)
        {
            if (backgroundWorker1.IsBusy)
                backgroundWorker1.CancelAsync();
            else
                label2.Text = "No cancel processing !!!";

            Debug.WriteLine("btnCalcel_Click() thread id : {0}", Thread.CurrentThread.ManagedThreadId);
        }
        #endregion

        #region backgroundworker DoWork event
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            Debug.WriteLine("backgroundWorker1_DoWork() thread id : {0}", Thread.CurrentThread.ManagedThreadId);

            int sum = 0;
            for(int i = 0; i<= 100; i++)
            {
                simulateHeavyWork();
                sum += i;
                backgroundWorker1.ReportProgress(i);

                if (backgroundWorker1.CancellationPending)
                {
                    e.Cancel = true;
                    backgroundWorker1.ReportProgress(0);
                    return;
                }
            }

            e.Result = sum;
        }
        #endregion

        #region simulate heavy work
        private void simulateHeavyWork()
        {
            Thread.Sleep(100);
        }
        #endregion

        #region backgroundworker ProgressChanged event
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
            label1.Text = e.ProgressPercentage.ToString() + " %";

            Debug.WriteLine("ProgressChanged() thread id : {0}", Thread.CurrentThread.ManagedThreadId);
        }
        #endregion

        #region backgroundworker RunWorkerCompleted event
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
                label1.Text = "Processing cancelled";
            else if (e.Error != null)
                label1.Text = e.Error.Message;
            else
                label1.Text = "Sum = " + e.Result.ToString();

            Debug.WriteLine("backgroundWorker1_RunWorkerCompleted() thread id : {0}", Thread.CurrentThread.ManagedThreadId);
        }
        #endregion

        #region program close
        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        #endregion

 


2. 두번째 프로그램


        private BackgroundWorker myWorker = null;

        #region MainForm() - BackgroundWorker create
        public MainForm()
        {
            InitializeComponent();
            myWorker = new BackgroundWorker();

            myWorker.WorkerReportsProgress = true;
            myWorker.WorkerSupportsCancellation = true;

            myWorker.DoWork += new DoWorkEventHandler(myWork_DoWork);
            myWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(myWorker_RunWorkerCompleted);
            myWorker.ProgressChanged += new ProgressChangedEventHandler(myWorker_ProgressChanged);
        }
        #endregion

        #region backgroundworker DoWork event
        void myWork_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker sendingWorker = sender as BackgroundWorker;
            object[] arrObjects = e.Argument as object[];

            int maxValue = (int)arrObjects[0];
            StringBuilder sb = new StringBuilder();

            float percentage = 0;
            for (int i = 0; i <= maxValue; i++)
            {
                sb.Append(string.Format("Counting number : {0}{1}", PerformHeavyOperation(i), Environment.NewLine));
                percentage = 100 / (float)maxValue * i;
                sendingWorker.ReportProgress((int)percentage);

                if (sendingWorker.CancellationPending)
                {
                    e.Cancel = true;
                    break;
                }
            }

            e.Result = sb.ToString();
        }
        #endregion

        #region backgroundworker RunWorkerCompleted event
        void myWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                lblStatus.Text = "User Cancelled";
            }
            else if (e.Error != null)
            {
                txtResult.Text = e.Error.ToString();
                lblStatus.Text = "Error";
            }
            else
            { 
                string result = e.Result.ToString();
                txtResult.Text = result;
                lblStatus.Text = "Done";
            }
        }
        #endregion

        #region backgroundworker ProgressChanged event
        void myWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            lblStatus.Text = string.Format("Counting number : {0} %...", e.ProgressPercentage.ToString());
        }
        #endregion

        #region simulate heavy work
        private int PerformHeavyOperation(int i)
        {
            System.Threading.Thread.Sleep(100);
            return i * 1000;
        }
        #endregion

        #region start buton click method
        private void btnStart_Click(object sender, EventArgs e)
        {
            int numericValue = (int)this.numericUpDown.Value;
            object[] arrObjects = new object[] { numericValue };

            if (!myWorker.IsBusy)
            {
                if (!string.IsNullOrEmpty(txtResult.Text))
                    txtResult.Text = "";

                myWorker.RunWorkerAsync(arrObjects);
            }
            else
                lblStatus.Text = "Work processing";
        }
        #endregion

        #region clear click method
        private void btnClear_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Clear data?", "Confirm", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.OK)
                txtResult.Text = "";
        }
        #endregion

        #region cancel buton click method
        private void btnCancel_Click(object sender, EventArgs e)
        {
            if (myWorker.IsBusy)
            { 
                myWorker.CancelAsync();
            }
            else
            {
                lblStatus.Text = "No cancel work";
            }
        }
        #endregion

1번 예제 소스 :

BackgroundWorker1.zip

 

2번 예제 소스 :

BackgroundWorker2.zip


'C#' 카테고리의 다른 글

멀티플(multiple) 윈도우 - 2  (0) 2015.05.07
데이타베이스 라이브러리  (0) 2015.04.22
텍스트 로그 파일 라이브러리 - 3  (0) 2015.02.21
텍스트 로그 파일 라이브러리 - 2  (0) 2015.02.21
멀티플(multiple) 윈도우 - 1  (0) 2015.01.24
posted by 따시쿵