zoukankan      html  css  js  c++  java
  • 通用的异步处理类和进度通知类及其示例

    在上文《我的界面进度条异步显示模式》中,我提到了使用异步处理显示进度条的时候,我觉得用起来比较顺手的一种组织代码的方法,相比起来,这种方法的最大特点就是把代码尽量地从界面层剥离,并且让界面之间的关联尽可能少些。

    我在处理过程中使用了一个封装了异步线程处理的一个抽象类,这个抽象类实现了异步处理的 Start,Abort, Pause 和 Resume 接口,大家用它来实现异步处理的时候,就可以象玩秒表一样随意地控制这些处理过程了。完整的代码如下:

        public abstract class AsyncWorker
        
    {
            
    public enum WorkState{Ready, Working, Pause,Resume,Aborted, Done, Error}

            
    private WorkState m_State;
            
    private bool m_Wait;
            
    private Thread m_Thread;

            
    protected AsyncWorker(bool wait)
            
    {
                m_State 
    = WorkState.Ready;
                m_Wait 
    = wait;
                m_Thread 
    = new Thread(new ThreadStart(Work));
            }


            
    public void Start()
            
    {
                OnStateChangedSync(WorkState.Ready);
                m_Thread.Start();
                
    while( m_Wait && m_Thread.IsAlive )
                
    {
                    OnIdle();
                    Thread.Sleep(
    200);
                }

            }


            
    public void Pause()
            
    {
                
    if( m_State == WorkState.Working)
                
    {
                    m_Thread.Suspend();
                    m_State 
    = WorkState.Pause;
                    OnStateChanged(WorkState.Pause);
                }

            }


            
    public void Resume()
            
    {
                
    if( m_State == WorkState.Pause )
                
    {
                    m_State 
    = WorkState.Working;
                    m_Thread.Resume();
                    OnStateChanged(WorkState.Resume);
                }

            }


            
    public void Abort()
            
    {
                
    if( m_State == WorkState.Working || m_State == WorkState.Pause )
                
    {
                    m_Thread.Abort();
                    m_State 
    = WorkState.Aborted;
                    OnStateChanged(WorkState.Aborted);
                }

            }


            
    private void Work()
            
    {
                
    try
                
    {
                    m_State 
    = WorkState.Working;
                    OnStateChangedSync(WorkState.Working);

                    DoWork();

                    m_State 
    = WorkState.Done;
                    OnStateChanged(WorkState.Done);
                }

                
    catch (Exception e)
                
    {
                    m_State 
    = WorkState.Error;
                    OnError(e);
                    OnStateChanged(WorkState.Error);
                }

            }


            
    protected abstract void DoWork();

            
    private void OnStateChangedSync(WorkState state)
            
    {
                
    if( StateChanged != null )
                    StateChanged(
    this, state);
            }


            
    private void OnStateChanged(WorkState state)
            
    {
                
    if( StateChanged != null )
                    StateChanged.BeginInvoke(
    this, state, nullnull);
            }


            
    protected void OnIdle()
            
    {
                
    if( Idle != null )
                
    {
                    
    lock(this)        // 有可能会很高频率调用
                        Idle(this);
                }

            }


            
    protected void OnError(Exception e)
            
    {
                
    if( Error != null )
                    Error.BeginInvoke(
    this, e, nullnull);
            }


            
    public delegate void StateChangedEventHandler(AsyncWorker sender, WorkState state);
            
    public delegate void IdleEventHandler(AsyncWorker sender);
            
    public delegate void ErrorEventHandler(AsyncWorker sender, Exception e);

            
    public event StateChangedEventHandler StateChanged;
            
    public event IdleEventHandler Idle;
            
    public event ErrorEventHandler Error;
        }



    在处理进度变化的时候,我使用了一个抽象的接口 IProgress,这个抽象接口提供外部对进度的查询功能,接口定义如下:

        /// <summary>
        
    /// 反映进度的变化的接口
        
    /// </summary>

        public interface IProgress
        
    {
            
    int Total{get;}
            
    int CurrentProgress{get;}
            
    string Description{get;}
        }


    在具体实现的时候,可以看我的 ProgressMoniter 的代码,这个是利用一个单独的线程来定期轮询 IProgress 接口进度变化,然后产生事件通知,是最好的说明例子,如果有人想修改成非轮询的方式,也很容易。

        public class ProgressMoniter : AsyncWorker
        
    {
            
    public delegate void ProgressEventHandler(string text, int percent);

            
    public event ProgressEventHandler Progress;

            IProgress m_Progress;
            
    private bool m_Exit;

            
    public bool Exit get return m_Exit; } set { m_Exit = value; } }

            
    public ProgressMoniter(IProgress progress) : base(false)
            
    {
                m_Progress 
    = progress;
                m_Exit 
    = false;
            }


            
    protected override void DoWork()
            
    {
                
    while!m_Exit )
                
    {
                    
    lock(m_Progress)
                        OnProgress(m_Progress.Description, m_Progress.Total, m_Progress.CurrentProgress);
                    Thread.Sleep(
    200);
                }

            }


            
    private void OnProgress(string description, int total, int progress)
            
    {
                
    if( Progress != null )
                    Progress.BeginInvoke(description, (
    int)((long)progress * 100 / (long)total), nullnull);
            }

        }
  • 相关阅读:
    CodeBlocks背景主题的设置
    Win7更改默认打开方式失败
    BAT命令介绍【转自Internet】
    Index of my articles
    一个表格说明RelativeLayout中的几个重要属性【Written By KillerLegend】
    有史以来最简单的三层实例(C#) ——转载自CSDN
    银联规定的MAC算法_转载
    Windows下ORACLE 10g安装与操作图解
    Oracle 在64位机器上使用PLSQL连接Oracle的问题(SQL * NET not properly installed)转载
    Linux系统下JDK和Tomcat安装配置
  • 原文地址:https://www.cnblogs.com/BigTall/p/115585.html
Copyright © 2011-2022 走看看