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

      BackgroundWorker是微软的在.net Framwork中添加的一个组件,主要对线程的访问提供了一种安全的方式。简单的说就是对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:线程结束时触发,主要有成功结束,发生异常或者取消时发生。

  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          }
108 

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

 

 

你可能感兴趣的:(background)