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

        }
  • 相关阅读:
    区别@ControllerAdvice 和@RestControllerAdvice
    Cannot determine embedded database driver class for database type NONE
    使用HttpClient 发送 GET、POST、PUT、Delete请求及文件上传
    Markdown语法笔记
    Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
    Mysql 查看连接数,状态 最大并发数(赞)
    OncePerRequestFilter的作用
    java连接MySql数据库 zeroDateTimeBehavior
    Intellij IDEA 安装lombok及使用详解
    ps -ef |grep xxx 输出的具体含义
  • 原文地址:https://www.cnblogs.com/BigTall/p/115585.html
Copyright © 2011-2022 走看看