• 通用的异步处理类和进度通知类及其示例


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

    我在处理过程中使用了一个封装了异步线程处理的一个抽象类,这个抽象类实现了异步处理的 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);
            }

        }
  • 相关阅读:
    解决.Net 4.0 A potentially dangerous Request.Form value was detected from the client 异常
    解决背景在360极速模式下不显示的问题
    ASP怎么解除文件上传200kb限制
    mysql导入数据出错
    ECShop出现Strict Standards: Only variables should be passed by reference in的解决方法
    phpmyadmin导入sql数据的纠结
    Veket_Porteus_Puppy安装器by双心
    多系统的福音,bcdedit找回传统启动菜单。取消(恢复)Modern UI风格启动菜单~菜单~
    关于fbinst-ud区的几点看法
    高速公路坐标高程计算软件4.2版本发布
  • 原文地址:https://www.cnblogs.com/BigTall/p/115585.html
Copyright © 2020-2023  润新知