异步窗体实现操作进度(ProgressWindow)

      前面写了几篇关于线程、BackGroundWorker等一下文章,现在主要对这些文章进行一个总结,写一篇关键异步窗体的,来实现操作的进度。

     对于大型作业来说,循环处理是一件极其耗时的事情,如果都在Application的主线程中去执行,用户的界面感觉就如同死机一般,但是如果添加了进度窗体(ProcessWindow)来说,就不同了,程序会显示出一个新的窗体,而且给用户的效果是非常好的。

     闲话少说,首先讲一下简单的原理:一般处理这样的事情都是一种模式,就是使用多线程或者使用微软封装好的线程控件(BackgroundWorker)去处理。原理都是一样的,就是在主线程中创建一个新的线程,我们成为子线程,子线程和主线程是并行工作的,主线程显示一个模式窗体,显示给用户看,子线程则去处理我们复杂的作业,并且提示主线程显示的模式窗体进度。知道子线程处理完一切作业,则通知模式窗体关闭或者进行其他的处理,流程图如下:

 

     

 

      这是简单的流程,下面是代码的实现:

      首先创建一个项目,名叫ProgressWindowForm,然后创建一个窗体名称叫做ProgressWindowForm,首先设置这个窗体不能最大化和关闭,在窗体上添加一个Progressbar、一个Label和Cancel按钮,代码如下:

        #region  委托
        
///   <summary>
        
///  设置显示值的委托
        
///   </summary>
        
///   <param name="text"></param>
         public   delegate   void  SetTextInvoker(String text);

        
///   <summary>
        
///  进度显示的委托
        
///   </summary>
        
///   <param name="val"></param>
         public   delegate   void  IncrementInvoker( int  val);

        
///   <summary>
        
///  跳转到
        
///   </summary>
        
///   <param name="val"></param>
         public   delegate   void  StepToInvoker( int  val);

        
///   <summary>
        
///  设置ProgressBar的范围
        
///   </summary>
        
///   <param name="minimum"></param>
        
///   <param name="maximum"></param>
         public   delegate   void  RangeInvoker( int  minimum,  int  maximum);
        
#endregion

        
#region  私有变量
        
///   <summary>
        
///  tilte
        
///   </summary>
         private  String title  =   "" ;

        
///   <summary>
        
///  初始线程
        
///   </summary>
         private  System.Threading.ManualResetEvent initResetEvent  =   new  System.Threading.ManualResetEvent( false );

        
///   <summary>
        
///  停止线程
        
///   </summary>
         private  System.Threading.ManualResetEvent abortResetEvent  =   new  System.Threading.ManualResetEvent( false );

        
///   <summary>
        
///  是否关闭
        
///   </summary>
         private   bool  requiresClose  =   true ;
        
#endregion

        
#region  方法
        
///   <summary>
        
///  开始进程
        
///   </summary>
        
///   <param name="minimum"> progressbar的最大值 </param>
        
///   <param name="maximum"> progressbar的最大值 </param>
         public   void  BeginThread( int  minimum,  int  maximum)
        {
            initResetEvent.WaitOne();
            Invoke(
new  RangeInvoker(DoBegin),  new   object [] { minimum, maximum });
        }

        
///   <summary>
        
///  开始进程
        
///   </summary>
         public   void  BeginThread()
        {
            initResetEvent.WaitOne();
            Invoke(
new  MethodInvoker(DoBegin));
        }

        
///   <summary>
        
///  设置范围
        
///   </summary>
        
///   <param name="minimum"> 最小值 </param>
        
///   <param name="maximum"> 最大值 </param>
         public   void  SetProgressRange( int  minimum,  int  maximum)
        {
            initResetEvent.WaitOne();
            Invoke(
new  RangeInvoker(DoSetRange),  new   object [] { minimum, maximum });
        }

        
///   <summary>
        
///  设置显示值
        
///   </summary>
        
///   <param name="text"> 显示值 </param>
         public   void  SetDisplayText(String text)
        {
            Invoke(
new  SetTextInvoker(DoSetText),  new   object [] { text });
        }

        
///   <summary>
        
///  增加显示值
        
///   </summary>
        
///   <param name="val"> 增加值 </param>
         public   void  Increment( int  val)
        {
            Invoke(
new  IncrementInvoker(DoIncrement),  new   object [] { val });
        }

        
///   <summary>
        
///  跳到摸个进度
        
///   </summary>
        
///   <param name="val"></param>
         public   void  StepTo( int  val)
        {
            Invoke(
new  StepToInvoker(DoStepTo),  new   object [] { val });
        }


        
///   <summary>
        
///  是否停止
        
///   </summary>
         public   bool  IsAborting
        {
            
get
            {
                
return  abortResetEvent.WaitOne( 0 false );
            }
        }

        
///   <summary>
        
///  结束进程
        
///   </summary>
         public   void  End()
        {
            
if  (requiresClose)
            {
                Invoke(
new  MethodInvoker(DoEnd));
            }
        }
        
#endregion

        
#region  私有方法
        
private   void  DoSetText(String text)
        {
            label.Text 
=  text;
        }

        
private   void  DoIncrement( int  val)
        {
            progressBar.Increment(val);
            UpdateStatusText();
        }

        
private   void  DoStepTo( int  val)
        {
            progressBar.Value 
=  val;
            UpdateStatusText();
        }

        
private   void  DoBegin( int  minimum,  int  maximum)
        {
            DoBegin();
            DoSetRange(minimum, maximum);
        }

        
private   void  DoBegin()
        {
            cancelButton.Enabled 
=   true ;
        }

        
private   void  DoSetRange( int  minimum,  int  maximum)
        {
            progressBar.Minimum 
=  minimum;
            progressBar.Maximum 
=  maximum;
            progressBar.Value 
=  minimum;
            title 
=  Text;
        }

        
private   void  DoEnd()
        {
            Close();
        }

        
private   void  UpdateStatusText()
        {
            Text 
=  title  +  String.Format( "  - {0}% 已完成 " , (progressBar.Value  *   100 /  (progressBar.Maximum  -  progressBar.Minimum));
        }

        
///   <summary>
        
///  强制停止进程
        
///   </summary>
         private   void  AbortWork()
        {
            abortResetEvent.Set();
        }
        
#endregion

        
///   <summary>
        
///  Raises the  <see cref="E:System.Windows.Forms.Form.Load"/>  event.
        
///   </summary>
        
///   <param name="e"> An  <see cref="T:System.EventArgs"/>  that contains the event data. </param>
         protected   override   void  OnLoad(EventArgs e)
        {
            
base .OnLoad(e);

            initResetEvent.Set();
        }

        
///   <summary>
        
///  Raises the  <see cref="E:System.Windows.Forms.Form.Closing"/>  event.
        
///   </summary>
        
///   <param name="e"> <see cref="T:System.ComponentModel.CancelEventArgs"/>  that contains the event data. </param>
         protected   override   void  OnClosing(CancelEventArgs e)
        {
            requiresClose 
=   false ;
            AbortWork();
            
base .OnClosed(e);
        }

        就这些,很简单的实现。

测试代码如下: 

       ///   <summary>
        
///  Handles the Click event of the buttonTest control.
        
///   </summary>
        
///   <param name="sender"> The source of the event. </param>
        
///   <param name="e"> The  <see cref="System.EventArgs"/>  instance containing the event data. </param>
         private   void  buttonTest_Click( object  sender, EventArgs e)
        {
            ProgressWindowForm progressWindowForm 
=   new  ProgressWindowForm();
            progressWindowForm.Text 
=   " 测试工作 " ;
            System.Threading.ThreadPool.QueueUserWorkItem(
new  System.Threading.WaitCallback(DoSomeWork), progressWindowForm);
            progressWindowForm.ShowDialog();
        }

        
///   <summary>
        
///  Does some work.
        
///   </summary>
        
///   <param name="status"> The status. </param>
         private   void  DoSomeWork( object  status)
        {
            ProgressWindowForm progressWindowForm 
=  status  as  ProgressWindowForm;
            
try
            {
                progressWindowForm.BeginThread(
0 1000 );
                
for  ( int  i  =   0 ; i  <   1000 ++ i)
                {
                    progressWindowForm.SetDisplayText(String.Format(
" 处理第{0}条. " , i));
                    progressWindowForm.StepTo(i);
                    
if  (progressWindowForm.IsAborting)
                    {
                        
return ;
                    }
                    System.Threading.Thread.Sleep(
100 );
                    
if  (progressWindowForm.IsAborting)
                    {
                        
return ;
                    }
                }
            }
            
catch  (Exception exception)
            {
                MessageBox.Show(exception.Message 
+  Environment.NewLine  +  exception.StackTrace);
            }
            
finally
            {
                
if  (progressWindowForm  !=   null )
                {
                    progressWindowForm.End();
                }
            }

        } 

示例代码下载 :ProgressWindow源代码

 

 

转载于:https://www.cnblogs.com/zhjp11/archive/2009/11/26/1610800.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值