我的界面进度条异步显示模式

系统的注册表坏了,又不想重装,于是考虑编一个程序来比较一下注册表的变化(我每装一个重要软件都会备份注册表)。在实际编程的时候,因为处理注册表的时间比较长,需要显示一个进度条,而且要异步处理,避免界面长时间没有响应的问题。

原来的处理方法采用过如下的两种(以下是伪代码):

None.gif class  Form1
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
void OnStartButtonClick()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        ProgressForm prog 
= new ProgressForm();
InBlock.gif        
// 预处理
InBlock.gif
        prog.ShowDialog();
InBlock.gif        
// 其他处理
ExpandedSubBlockEnd.gif
    }

ExpandedBlockEnd.gif}

None.gif
None.gif
class  ProgressForm
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
private Timer m_Timer;    //设置时钟, 100ms
InBlock.gif
    
InBlock.gif    
void TimerTick() // 时钟触发
ExpandedSubBlockStart.gifContractedSubBlock.gif
    dot.gif{
InBlock.gif        m_Timer.Enable 
= false;    // 时钟只需要用一次
InBlock.gif        
// 以下开始正式的处理过程
InBlock.gif
        WorkThread th = new WorkThread(dot.gif);
InBlock.gif        th.ProgressEvent 
+= new ProgressEvent(ProgressCallback);
InBlock.gif        
// dot.gif
ExpandedSubBlockEnd.gif
    }

InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
void ProgressCallback(dot.gif)dot.gifdot.gif }
ExpandedBlockEnd.gif}

None.gif

另外一种是觉得使用时钟不好,绕来绕去太麻烦,又想把调用 WorkThread 部分代码放到 Form1 中,但是如此一来,ShowDialog 就不能用了,代码变成了如下:

None.gif class  Form1
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    ProgressForm prog;
InBlock.gif    
void OnStartButtonClick()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        prog 
= new ProgressForm();
InBlock.gif        
// 预处理
InBlock.gif
        this.Enabled = false;    // 禁止自身,保证 ProgressForm 在窗口前面
InBlock.gif
        prog.Show();    
InBlock.gif
InBlock.gif        
// 开始处理        
InBlock.gif
        WorkThread th = new WorkThread(dot.gif);
InBlock.gif        th.ProgressEvent 
+= new ProgressEvent(ProgressCallback);
InBlock.gif        
// 其他处理
ExpandedSubBlockEnd.gif
    }

InBlock.gif    
InBlock.gif    
void ProgressCallback(dot.gif)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        prog.DisplayProgress(total, percent, text);
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}

None.gif
None.gif
class  ProgressForm
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public void DisplayProgress( dot.gif )
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
// 刷新进度条
ExpandedSubBlockEnd.gif
    }

ExpandedBlockEnd.gif}

None.gif

但是使用过程中发现窗口这样的关系就变得很尴尬,而且,就这样的代码,我始终无法把ProgressForm中的 “中断操作” 按钮的代码找到一个满意的实现方法。

最后,经过重新的考虑和设计,最终的代码把 WorkThread 设计了一个通用的接口,屏蔽了使用线程的一些繁琐,并且提供了 Start, Pause, Resume,Abort 接口,并通过事件发送对外通知。另外,取消频繁调用进度通知的代码,提供了一个进度查询接口 IProgress,由专门的进度监控线程ProgressMoniter 来监视进度并通知ProgressForm刷新界面。最后的外部代码如下:

None.gif class  Form1
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
void OnStartButtonClick()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        ProgressForm prog 
= new ProgressForm();
InBlock.gif
InBlock.gif        
// 预处理
InBlock.gif        
InBlock.gif        
// 生成工作线程    
InBlock.gif
        WorkThread m_Worker = new WorkThread(dot.gif);
InBlock.gif        m_Worker.Idle 
+= new IdleEventHandler(m_Worker_Idle);
InBlock.gif        m_Worker.Error 
+= new ErrorEventHandler(m_Worker_Error);
InBlock.gif        m_Worker.StateChanged 
+= new StateChangedEventHandler(m_Worker_StateChanged);
InBlock.gif
InBlock.gif        
// 生成监控线程
InBlock.gif
        ProgressMoniter m_Moniter = new ProgressMoniter(m_Worker);
InBlock.gif
InBlock.gif        prog.Assign(m_Moniter);        
// ProgressForm 关联监控线程的进度变化事件
InBlock.gif
        m_Worker.Start();        // 开始工作
InBlock.gif
        m_Moniter.Start();        // 开始监控进度
InBlock.gif

InBlock.gif        prog.ShowDialog();    
// ShowDialog显示,这下不用 this.Enable = false 了
InBlock.gif
InBlock.gif        
// ShowDialog会一直等待工作完成之后才返回,然后作其他处理
ExpandedSubBlockEnd.gif
    }

InBlock.gif
ExpandedBlockEnd.gif}

None.gif
None.gif
class  ProgressForm
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public void Assign(ProgressMoniter moniter)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        DisplayProgress(
"ready"0);
InBlock.gif
InBlock.gif        
this.btnCancel.Enabled = true;    // 允许中断
InBlock.gif
        m_Worker = moniter;
InBlock.gif        moniter.Progress 
+= new ProgressEventHandler(DisplayProgress);    // 挂接事件
ExpandedSubBlockEnd.gif
    }

InBlock.gif        
InBlock.gif    
public void DisplayProgress( dot.gif )
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
// 刷新进度条
ExpandedSubBlockEnd.gif
    }

ExpandedBlockEnd.gif}

None.gif
None.gif

其他部分的代码和实现在下一篇文章里,等一下我就写。 teeth_smile.gif

请看《 通用的异步处理类和进度通知类及其示例》。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值