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

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

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

class Form1
{
    
void OnStartButtonClick()
    
{
        ProgressForm prog 
= new ProgressForm();
        
// 预处理
        prog.ShowDialog();
        
// 其他处理
    }

}


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

    
    
void ProgressCallback() }
}


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

class Form1
{
    ProgressForm prog;
    
void OnStartButtonClick()
    
{
        prog 
= new ProgressForm();
        
// 预处理
        this.Enabled = false;    // 禁止自身,保证 ProgressForm 在窗口前面
        prog.Show();    

        
// 开始处理        
        WorkThread th = new WorkThread();
        th.ProgressEvent 
+= new ProgressEvent(ProgressCallback);
        
// 其他处理
    }

    
    
void ProgressCallback()
    
{
        prog.DisplayProgress(total, percent, text);
    }


}


class ProgressForm
{
    
public void DisplayProgress(  )
    
{
        
// 刷新进度条
    }

}


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

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

class Form1
{
    
void OnStartButtonClick()
    
{
        ProgressForm prog 
= new ProgressForm();

        
// 预处理
        
        
// 生成工作线程    
        WorkThread m_Worker = new WorkThread();
        m_Worker.Idle 
+= new IdleEventHandler(m_Worker_Idle);
        m_Worker.Error 
+= new ErrorEventHandler(m_Worker_Error);
        m_Worker.StateChanged 
+= new StateChangedEventHandler(m_Worker_StateChanged);

        
// 生成监控线程
        ProgressMoniter m_Moniter = new ProgressMoniter(m_Worker);

        prog.Assign(m_Moniter);        
// ProgressForm 关联监控线程的进度变化事件
        m_Worker.Start();        // 开始工作
        m_Moniter.Start();        // 开始监控进度

        prog.ShowDialog();    
// ShowDialog显示,这下不用 this.Enable = false 了

        
// ShowDialog会一直等待工作完成之后才返回,然后作其他处理
    }


}


class ProgressForm
{
    
public void Assign(ProgressMoniter moniter)
    
{
        DisplayProgress(
"ready"0);

        
this.btnCancel.Enabled = true;    // 允许中断
        m_Worker = moniter;
        moniter.Progress 
+= new ProgressEventHandler(DisplayProgress);    // 挂接事件
    }

        
    
public void DisplayProgress(  )
    
{
        
// 刷新进度条
    }

}



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

请看《通用的异步处理类和进度通知类及其示例》。

posted on 2005-03-09 15:28  老翅寒暑  阅读(2501)  评论(0编辑  收藏  举报

导航