多线程(1)

source:http://www.cnblogs.com/zhjp11/archive/2009/11/19/1605986.html

 前不久写了一个项目,其中需要处理大量的数据,这些数据都是记录型的,对这些数据进行处理是一个非常耗时的事情,.net在处理这些使用的过程中,就好像死机一样一动不动。这样给用户的感觉非常的不好。例如如下的例子,我们在一个窗体上放置一个ProgressBar,然后对ProgressBar进行循环添加,例如:

 1          private   void  btnProcess_Click( object  sender, EventArgs e)
 2          {
 3               int  nStart  =  Convert.ToInt32(txtStart.Text);
 4               int  nEnd  =  Convert.ToInt32(txtEnd.Text);
 5 
 6              prgProcess.Minimum  =  nStart;
 7              prgProcess.Maximum  =  nEnd;
 8               for  ( int  nValue  =  nStart; nValue  <=  nEnd; nValue ++ )
 9              {
10                  lblStatus.Text  =   " Processing item:  "   +  Convert.ToString(nValue);
11                  prgProcess.Value  =  nValue;
12              } } 

      这段代码运行时正常的,但是对于数据量很大的时候,比如txtEnd.Text设置成1000000,这个时候界面上的进度条也许就是个固定值,一动不动,而且lblStatus.Text的现实也是为空,这是很正常的。程序就如同死机一样。当然,我们可以在循环中添加Application.DoEvents();使系统在空闲的时间处理其他的事情,这样系统的效果会好些。例如:

 

 1  private   void  btnProcess_Click( object  sender, EventArgs e)
 2          {
 3               int  nStart  =  Convert.ToInt32(txtStart.Text);
 4               int  nEnd  =  Convert.ToInt32(txtEnd.Text);
 5 
 6              prgProcess.Minimum  =  nStart;
 7              prgProcess.Maximum  =  nEnd;
 8               for  ( int  nValue  =  nStart; nValue  <=  nEnd; nValue ++ )
 9              {
10                  lblStatus.Text  =   " Processing item:  "   +  Convert.ToString(nValue);
11                  prgProcess.Value  =  nValue;
12 
13                  Application.DoEvents();
14              }
15          }

 

      但这些不是本文的重点,本文的重点是使用多线程的的方式去处理这些内容,我们将在此窗体中添加Tread去处理这些复杂的操作。这样的效果会比Application.DoEvents();更好。

      还是在原来的窗体上,我们使用线程的方式去处理。

 1           delegate   void  DelegateType( int  x);
 2          DelegateType TheDelegate;
 3 
 4           int  StartFrom, EndTo;
 5 
 6           private   void  btnStartThreaded_Click( object  sender, EventArgs e)
 7          {
 8              TheDelegate  =  MessageHandler;
 9 
10              StartFrom  =  Convert.ToInt32(txtStart.Text);
11              EndTo  =  Convert.ToInt32(txtEnd.Text);
12 
13              prgProcess.Minimum  =  StartFrom;
14              prgProcess.Maximum  =  EndTo;
15 
16              btnStartThreaded.Enabled  =   false ;
17 
18              Thread MyThread  =   new  Thread(ProcessRoutine);
19              MyThread.Start();
20          }
21 
22           void  MessageHandler( int  nProgress)
23          {
24              lblStatus.Text  =   " Processing item:  "   +  Convert.ToString(nProgress);
25              prgProcess.Value  =  nProgress;
26          }
27 
28           void  ProcessRoutine()
29          { 
30               for  ( int  nValue  =  StartFrom; nValue  <=  EndTo; nValue ++ )
31              {
32                   this .Invoke( this .TheDelegate, nValue);
33              }

34         }

       这个是使用线程的方法去处理,但是问题还是有的,虽然线程处理了用户界面效果的问题,但是对于大数据量处理过程中,很耗时的,用户可能会去取消自己的操作,所以我们要添加方法去对自己的线程取消。微软这个方面做的很好,它提供了ManualResetEvent的委托类,可以轻松的对线程进行取消。代码如下:

       首先添加ManualResetEvent的委托:

   ManualResetEvent CancelEvent = new ManualResetEvent(false); 

         private   void  btnCancelButton_Click( object  sender, EventArgs e)
        {
            btnCancelButton.Enabled 
=   false ;

            CancelEvent.Set();
            MyThread.Join();

            lblStatus.Text 
=   " Cancelled! " ;

        } 

        修改ProcessRoutine的代码如下:

   void  ProcessRoutine()
        {
            
for  ( int  nValue  =  StartFrom; nValue  <=  EndTo; nValue ++ )
            {

                 if  (CancelEvent.WaitOne( 0 false ==   true )
                {
                    
return ;
                }
                
this .BeginInvoke( this .TheDelegate, nValue);
                Thread.Sleep(
200 );
            }
        }

       另外一点,我们还可以对线程进行扩充,就是将线程的暂停和继续,这个就很简单了,就是对线程的Suspend和Resume,只要再添加按钮设置线程的Suspend和Resume就可以了。代码如下:

        bool  IsThreadPaused;
        private   void  btnPause_Click( object  sender, EventArgs e)
        {
            
if  ( ! IsThreadPaused)
            {
                IsThreadPaused 
=   true ;
                MyThread.Suspend();
                btnPause.Text 
=   " Resume " ;
                lblStatus.Text 
=   " Paused! " ;
                btnCancelButton.Enabled 
=   false ;
            }
            
else
            {
                IsThreadPaused 
=   false ;
                MyThread.Resume();
                btnPause.Text 
=   " Pause " ;
                btnCancelButton.Enabled 
=   true ;
            }
        }

  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值