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);
            }

        }
  • 相关阅读:
    Springboot 之 自定义配置文件及读取配置文件
    SQLSERVER系统视图 sql server系统表详细说明
    MySQL Workbench建表时 PK NN UQ BIN UN ZF AI 的含义
    使用Ecplise git commit时出现"There are no stages files"
    maven添加sqlserver的jdbc驱动包
    java将XML文档转换成json格式数据
    java将XML文档转换成json格式数据
    cannot be resolved. It is indirectly referenced from required .class files
    org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.util.Date from String value '2012-12-12 12:01:01': not a valid representation (error: Can not parse date "2012-12-
    @Autowired注解和静态方法 NoClassDefFoundError could not initialize class 静态类
  • 原文地址:https://www.cnblogs.com/BigTall/p/115585.html
Copyright © 2011-2022 走看看