线程封装组件(BackgroundWorker)和线程(Thread)

BackgroundWorker位于System.ComponentModel下,是一个继承了Component的组件,微软官方的解释为:Executes an operation on a separate thread.就是说,开始一个新的线程执行操作。

  首先介绍一下BackgroundWorker的相关属性和方法:

  属性:

    WorkerReportsProgress:是否可以报告进度。

    WorkerSupportsCancellation:是否允许异步中止。

    IsBusy:是否在运行。

    CancellationPending:判断BackgroundWorker是否已经异步取消。

  方法:

    RunWorkerAsync:开始执行任务。触发DoWork事件

    ReportProgress:异步提醒,触发ProgressChanged事件,但是这个如果可以使用,必须设置WorkerReportsProgress为True

    CancelAsync:取消BackgroundWorker操作。

  事件:

    DoWork:执行RunWorkerAsync后触发,异步执行的认为。

    ProgressChanged:执行ReportProgress时触发,异步获得进度。

    RunWorkerCompleted:线程结束时触发,主要有成功结束,发生异常或者取消时发生。

backgroundworker

Thread相对来说就简单了,但是使用起来就比较麻烦了。Thread位于System.Threading的名空间下,是一个可以独立创建和操作一个线程,并且对线程进行设置优先级和获得状态的一个不可继承的类。

下面是我做的一个例子,来比较他们两个的使用。

建立一个窗体,放置了两个TextBox,分别为设置开始和结束的Progree的值,放置两个ProgressBar,分别设置为线程的Progressbar和BackGroundWorker的ProgressBar。另外放置按钮为StartBackGroundWorker,StartThread,CancelBackGroundWorker,CancelThread和PauseThread。

BackGroundWorker的使用就非常简单:

1         /// <summary>
2         /// Handles the Click event of the btnBackGroundWorker control.
3         /// </summary>
4         /// <param name="sender">The source of the event.</param>
5         /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
6         private void btnBackGroundWorker_Click(object sender, EventArgs e)
7         {
8             StartFrom = Convert.ToInt32(txtStart.Text);
9             EndTo = Convert.ToInt32(txtEnd.Text);
10 
11             progressBarThread.Minimum = StartFrom;
12             progressBarThread.Maximum = EndTo;
13 
14             this.btnBackGroundWorker.Enabled = false;
15 
16             this.backgroundWorker.RunWorkerAsync();
17         }
18 
19         /// <summary>
20         /// Handles the DoWork event of the backgroundWorker control.
21         /// </summary>
22         /// <param name="sender">The source of the event.</param>
23         /// <param name="e">The <see cref="System.ComponentModel.DoWorkEventArgs"/> instance containing the event data.</param>
24         private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
25         {
26             for (int nValue = StartFrom; nValue <= EndTo; nValue++)
27             {
28                 if (this.backgroundWorker.CancellationPending)
29                 {
30                     e.Cancel = true;
31                     return;
32                 }
33                 this.backgroundWorker.ReportProgress(nValue);
34                 Thread.Sleep(200);
35             }
36         }
37 
38         /// <summary>
39         /// Handles the ProgressChanged event of the backgroundWorker control.
40         /// </summary>
41         /// <param name="sender">The source of the event.</param>
42         /// <param name="e">The <see cref="System.ComponentModel.ProgressChangedEventArgs"/> instance containing the event data.</param>
43         private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
44         {
45             this.prgProcessBackGroundWorker.Value = e.ProgressPercentage;
46         }
47 
48         /// <summary>
49         /// Handles the RunWorkerCompleted event of the backgroundWorker control.
50         /// </summary>
51         /// <param name="sender">The source of the event.</param>
52         /// <param name="e">The <see cref="System.ComponentModel.RunWorkerCompletedEventArgs"/> instance containing the event data.</param>
53         private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
54         {
55             // 取消
56             if (e.Cancelled)
57             {
58                 MessageBox.Show("Cancelled");
59             }
60             // 出现错误
61             else if (e.Error != null)
62             {
63                 MessageBox.Show(e.Error.Message + Environment.NewLine + e.Error.StackTrace);
64             }
65             // 完成
66             else
67             {
68                 MessageBox.Show("Completed");
69                 this.btnBackGroundWorker.Enabled = true;
70             }
71         }
72 
73         /// <summary>
74         /// Handles the Click event of the btnCancelBackgroundWoker control.
75         /// </summary>
76         /// <param name="sender">The source of the event.</param>
77         /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
78         private void btnCancelBackgroundWoker_Click(object sender, EventArgs e)
79         {
80             this.backgroundWorker.CancelAsync();
81         }

  

Thread的使用就比较麻烦了,对于尤其是对异步提醒来说,需要写委托,代码量是很多,但是对于BackgroundWorker来说,却没有线程暂停和继续的方法。但是对于一般的来说,这些功能也是不用的,而且在微软的文档中还提到了,Thread的Resume和Suspend已经不推荐使用。

1        // 声明委托 
2         delegate void DelegateType(int x);
3        DelegateType TheDelegate;
4 
5         // ProgressBar的开始和结束值
6         int StartFrom, EndTo;
7 
8         // 是否线程暂停
9         bool IsThreadPaused;
10 
11         ManualResetEvent CancelEvent = new ManualResetEvent(false);
12         Thread MyThread;
13 
14         /// <summary>
15         /// 委托的消息事件
16         /// </summary>
17         /// <param name="nProgress">进度值</param>
18         private void MessageHandler(int nProgress)
19         {
20             lblThreadStatus.Text = "处理: " + Convert.ToString(nProgress);
21             progressBarThread.Value = nProgress;
22 
23             if (nProgress == progressBarThread.Maximum)
24             {
25                 MessageBox.Show("Completed");
26                 this.btnTread.Enabled = true;
27             }
28         }
29 
30         /// <summary>
31         /// Handles the Click event of the btnTread control.
32         /// </summary>
33         /// <param name="sender">The source of the event.</param>
34         /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
35         private void btnTread_Click(object sender, EventArgs e)
36         {
37             TheDelegate = MessageHandler;
38 
39             StartFrom = Convert.ToInt32(txtStart.Text);
40             EndTo = Convert.ToInt32(txtEnd.Text);
41 
42             progressBarThread.Minimum = StartFrom;
43             progressBarThread.Maximum = EndTo;
44 
45             btnTread.Enabled = false;
46 
47             IsThreadPaused = false;
48             MyThread = new Thread(ProcessRoutine);
49             MyThread.Start();
50         }
51 
52         /// <summary>
53         /// Processes the routine.
54         /// </summary>
55         private void ProcessRoutine()
56         {
57             for (int nValue = StartFrom; nValue <= EndTo; nValue++)
58             {
59                 // 判断是否取消
60                 if (CancelEvent.WaitOne(0, false) == true)
61                 {
62                     return;
63                 }
64                 this.BeginInvoke(this.TheDelegate, nValue);
65                 Thread.Sleep(200);
66             }
67         }
68 
69         /// <summary>
70         /// Handles the Click event of the btnCancelThread control.
71         /// </summary>
72         /// <param name="sender">The source of the event.</param>
73         /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
74         private void btnCancelThread_Click(object sender, EventArgs e)
75         {
76             btnCancelThread.Enabled = false;
77             btnPauseThread.Enabled = false;
78 
79             CancelEvent.Set();
80             MyThread.Join();
81         }
82 
83         /// <summary>
84         /// Handles the Click event of the btnPauseThread control.
85         /// </summary>
86         /// <param name="sender">The source of the event.</param>
87         /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
88         private void btnPauseThread_Click(object sender, EventArgs e)
89         {
90             // Bad approach!
91             if (!IsThreadPaused)
92             {
93                 IsThreadPaused = true;
94                 MyThread.Suspend();
95                 btnPauseThread.Text = "Resume Thread";
96 
97                 // Disallow Cancel
98                 btnCancelThread.Enabled = false;
99             }
100             else
101             {
102                 IsThreadPaused = false;
103                 MyThread.Resume();
104                 btnPauseThread.Text = "Pause Thread";
105                 btnCancelThread.Enabled = true;
106             }
107         }

 

比较起来,两个是完全相同的,对于Thread来说,灵活性就比较好了,BackgroundWorker的使用就相对来说简单了。

 

转载地址:http://www.cnblogs.com/valentine/archive/2011/04/21/2023300.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值