我的界面进度条异步显示模式
系统的注册表坏了,又不想重装,于是考虑编一个程序来比较一下注册表的变化(我每装一个重要软件都会备份注册表)。在实际编程的时候,因为处理注册表的时间比较长,需要显示一个进度条,而且要异步处理,避免界面长时间没有响应的问题。
原来的处理方法采用过如下的两种(以下是伪代码):
class Form1
{
void OnStartButtonClick()
{
ProgressForm prog = new ProgressForm();
// 预处理
prog.ShowDialog();
// 其他处理
}
}

class ProgressForm
{
private Timer m_Timer; //设置时钟, 100ms
void TimerTick() // 时钟触发
{
m_Timer.Enable = false; // 时钟只需要用一次
// 以下开始正式的处理过程
WorkThread th = new WorkThread(
);
th.ProgressEvent += new ProgressEvent(ProgressCallback);
// 
}
void ProgressCallback(
){
}
}

另外一种是觉得使用时钟不好,绕来绕去太麻烦,又想把调用 WorkThread 部分代码放到 Form1 中,但是如此一来,ShowDialog 就不能用了,代码变成了如下:
class Form1
{
ProgressForm prog;
void OnStartButtonClick()
{
prog = new ProgressForm();
// 预处理
this.Enabled = false; // 禁止自身,保证 ProgressForm 在窗口前面
prog.Show();

// 开始处理
WorkThread th = new WorkThread(
);
th.ProgressEvent += new ProgressEvent(ProgressCallback);
// 其他处理
}
void ProgressCallback(
)
{
prog.DisplayProgress(total, percent, text);
}

}

class ProgressForm
{
public void DisplayProgress(
)
{
// 刷新进度条
}
}

但是使用过程中发现窗口这样的关系就变得很尴尬,而且,就这样的代码,我始终无法把ProgressForm中的 “中断操作” 按钮的代码找到一个满意的实现方法。
最后,经过重新的考虑和设计,最终的代码把 WorkThread 设计了一个通用的接口,屏蔽了使用线程的一些繁琐,并且提供了 Start, Pause, Resume,Abort 接口,并通过事件发送对外通知。另外,取消频繁调用进度通知的代码,提供了一个进度查询接口 IProgress,由专门的进度监控线程ProgressMoniter 来监视进度并通知ProgressForm刷新界面。最后的外部代码如下:
class Form1
{
void OnStartButtonClick()
{
ProgressForm prog = new ProgressForm();

// 预处理
// 生成工作线程
WorkThread m_Worker = new WorkThread(
);
m_Worker.Idle += new IdleEventHandler(m_Worker_Idle);
m_Worker.Error += new ErrorEventHandler(m_Worker_Error);
m_Worker.StateChanged += new StateChangedEventHandler(m_Worker_StateChanged);

// 生成监控线程
ProgressMoniter m_Moniter = new ProgressMoniter(m_Worker);

prog.Assign(m_Moniter); // ProgressForm 关联监控线程的进度变化事件
m_Worker.Start(); // 开始工作
m_Moniter.Start(); // 开始监控进度

prog.ShowDialog(); // ShowDialog显示,这下不用 this.Enable = false 了

// ShowDialog会一直等待工作完成之后才返回,然后作其他处理
}

}

class ProgressForm
{
public void Assign(ProgressMoniter moniter)
{
DisplayProgress("ready", 0);

this.btnCancel.Enabled = true; // 允许中断
m_Worker = moniter;
moniter.Progress += new ProgressEventHandler(DisplayProgress); // 挂接事件
}
public void DisplayProgress(
)
{
// 刷新进度条
}
}


其他部分的代码和实现在下一篇文章里,等一下我就写。
请看《通用的异步处理类和进度通知类及其示例》。
原来的处理方法采用过如下的两种(以下是伪代码):































另外一种是觉得使用时钟不好,绕来绕去太麻烦,又想把调用 WorkThread 部分代码放到 Form1 中,但是如此一来,ShowDialog 就不能用了,代码变成了如下:


































但是使用过程中发现窗口这样的关系就变得很尴尬,而且,就这样的代码,我始终无法把ProgressForm中的 “中断操作” 按钮的代码找到一个满意的实现方法。
最后,经过重新的考虑和设计,最终的代码把 WorkThread 设计了一个通用的接口,屏蔽了使用线程的一些繁琐,并且提供了 Start, Pause, Resume,Abort 接口,并通过事件发送对外通知。另外,取消频繁调用进度通知的代码,提供了一个进度查询接口 IProgress,由专门的进度监控线程ProgressMoniter 来监视进度并通知ProgressForm刷新界面。最后的外部代码如下:
















































其他部分的代码和实现在下一篇文章里,等一下我就写。

请看《通用的异步处理类和进度通知类及其示例》。

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