프로그램 설명
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번 예제 소스 :
2번 예제 소스 :
'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 |