通用的异步处理类和进度通知类及其示例
在上文《我的界面进度条异步显示模式》中,我提到了使用异步处理显示进度条的时候,我觉得用起来比较顺手的一种组织代码的方法,相比起来,这种方法的最大特点就是把代码尽量地从界面层剥离,并且让界面之间的关联尽可能少些。
我在处理过程中使用了一个封装了异步线程处理的一个抽象类,这个抽象类实现了异步处理的 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, null, null);
}

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

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

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


















































































































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









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


































公众号:老翅寒暑
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了