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


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

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

    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(  )
        
    {
            
    // 刷新进度条
        }

    }



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

    请看《通用的异步处理类和进度通知类及其示例》。
  • 相关阅读:
    lvs实现故障转移(backup)
    shell计算
    CEGUI 聊天对话框
    SetRenderState 设置渲染状态【转】
    MFC 弹出对话框
    DrawIndexedPrimitive函数的详细解释【转】
    IDirect3DDevice9::Clear 【转】
    manifest 文件错误
    D3DXMatrixLookAtLH 【转】
    D3D中的网格(Mesh)
  • 原文地址:https://www.cnblogs.com/BigTall/p/115571.html
Copyright © 2020-2023  润新知