zoukankan      html  css  js  c++  java
  • 我的界面进度条异步显示模式

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

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

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

    }



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

    请看《通用的异步处理类和进度通知类及其示例》。
  • 相关阅读:
    Checking Types Against the Real World in TypeScript
    nexus pip proxy config
    go.rice 强大灵活的golang 静态资源嵌入包
    几个golang 静态资源嵌入包
    rpm 子包创建学习
    Rpm Creating Subpackages
    ava 类似jest snapshot 功能试用
    ava js 测试框架基本试用
    The Architectural Principles Behind Vrbo’s GraphQL Implementation
    graphql-compose graphql schema 生成工具集
  • 原文地址:https://www.cnblogs.com/BigTall/p/115571.html
Copyright © 2011-2022 走看看