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

博客给出了通用的异步处理类和进度通知类的代码示例。异步处理类 AsyncWorker 包含工作状态枚举,有启动、暂停、恢复、中止等方法;进度通知类 ProgressMoniter 继承自 AsyncWorker,可监控进度变化并通过事件通知。
在上文 《我的界面进度条异步显示模式》中,我提到了使用异步处理显示进度条的时候,我觉得用起来比较顺手的一种组织代码的方法,相比起来,这种方法的最大特点就是把代码尽量地从界面层剥离,并且让界面之间的关联尽可能少些。

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

None.gif      public   abstract   class  AsyncWorker
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public enum WorkStatedot.gif{Ready, Working, Pause,Resume,Aborted, Done, Error}
InBlock.gif
InBlock.gif        
private WorkState m_State;
InBlock.gif        
private bool m_Wait;
InBlock.gif        
private Thread m_Thread;
InBlock.gif
InBlock.gif        
protected AsyncWorker(bool wait)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            m_State 
= WorkState.Ready;
InBlock.gif            m_Wait 
= wait;
InBlock.gif            m_Thread 
= new Thread(new ThreadStart(Work));
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public void Start()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            OnStateChangedSync(WorkState.Ready);
InBlock.gif            m_Thread.Start();
InBlock.gif            
while( m_Wait && m_Thread.IsAlive )
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                OnIdle();
InBlock.gif                Thread.Sleep(
200);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public void Pause()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if( m_State == WorkState.Working)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                m_Thread.Suspend();
InBlock.gif                m_State 
= WorkState.Pause;
InBlock.gif                OnStateChanged(WorkState.Pause);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public void Resume()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if( m_State == WorkState.Pause )
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                m_State 
= WorkState.Working;
InBlock.gif                m_Thread.Resume();
InBlock.gif                OnStateChanged(WorkState.Resume);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public void Abort()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if( m_State == WorkState.Working || m_State == WorkState.Pause )
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                m_Thread.Abort();
InBlock.gif                m_State 
= WorkState.Aborted;
InBlock.gif                OnStateChanged(WorkState.Aborted);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private void Work()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                m_State 
= WorkState.Working;
InBlock.gif                OnStateChangedSync(WorkState.Working);
InBlock.gif
InBlock.gif                DoWork();
InBlock.gif
InBlock.gif                m_State 
= WorkState.Done;
InBlock.gif                OnStateChanged(WorkState.Done);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                m_State 
= WorkState.Error;
InBlock.gif                OnError(e);
InBlock.gif                OnStateChanged(WorkState.Error);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
protected abstract void DoWork();
InBlock.gif
InBlock.gif        
private void OnStateChangedSync(WorkState state)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if( StateChanged != null )
InBlock.gif                StateChanged(
this, state);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private void OnStateChanged(WorkState state)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if( StateChanged != null )
InBlock.gif                StateChanged.BeginInvoke(
this, state, nullnull);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
protected void OnIdle()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if( Idle != null )
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
lock(this)        // 有可能会很高频率调用
InBlock.gif
                    Idle(this);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
protected void OnError(Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if( Error != null )
InBlock.gif                Error.BeginInvoke(
this, e, nullnull);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public delegate void StateChangedEventHandler(AsyncWorker sender, WorkState state);
InBlock.gif        
public delegate void IdleEventHandler(AsyncWorker sender);
InBlock.gif        
public delegate void ErrorEventHandler(AsyncWorker sender, Exception e);
InBlock.gif
InBlock.gif        
public event StateChangedEventHandler StateChanged;
InBlock.gif        
public event IdleEventHandler Idle;
InBlock.gif        
public event ErrorEventHandler Error;
ExpandedBlockEnd.gif    }

None.gif


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

ExpandedBlockStart.gif ContractedBlock.gif      /**/ /// <summary>
InBlock.gif    
/// 反映进度的变化的接口
ExpandedBlockEnd.gif    
/// </summary>

None.gif      public   interface  IProgress
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif        
int Totaldot.gif{get;}
ExpandedSubBlockStart.gifContractedSubBlock.gif        
int CurrentProgressdot.gif{get;}
ExpandedSubBlockStart.gifContractedSubBlock.gif        
string Descriptiondot.gif{get;}
ExpandedBlockEnd.gif    }


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

None.gif      public   class  ProgressMoniter : AsyncWorker
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
public delegate void ProgressEventHandler(string text, int percent);
InBlock.gif
InBlock.gif        
public event ProgressEventHandler Progress;
InBlock.gif
InBlock.gif        IProgress m_Progress;
InBlock.gif        
private bool m_Exit;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public bool Exit dot.gifget dot.gifreturn m_Exit; } set dot.gif{ m_Exit = value; } }
InBlock.gif
InBlock.gif        
public ProgressMoniter(IProgress progress) : base(false)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            m_Progress 
= progress;
InBlock.gif            m_Exit 
= false;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
protected override void DoWork()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
while!m_Exit )
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
lock(m_Progress)
InBlock.gif                    OnProgress(m_Progress.Description, m_Progress.Total, m_Progress.CurrentProgress);
InBlock.gif                Thread.Sleep(
200);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

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

ExpandedBlockEnd.gif    }

转载于:https://www.cnblogs.com/BigTall/archive/2005/03/09/115585.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值