由于一直以来都是在做ASP.NET 对于多线程这一块涉猎不深 觉得趁着入职之前好好练习一下多线程编程 多线程最简单直观的例子估计就是进度条了 同时由于还涉及到UI线程 更加可以了解一下winform编程方面一些原则
一般来讲 进度条可以有两种做法 一种是两个线程 一个UI线程 这是必须的 另一个则是耗时操作进程 同时通过回调 实时通知UI线度变化 UI线程接受到这些进度变化来进行相应的UI更新 但是这样子两者的耦合过高 很难分离出来一个通用的控件(因为每个耗时操作中必须包含一个委托 该委托来通知UI线程 我这边有进度发生变化了 但是耗时操作时交给调用方去实现的 所以相当于是调用方知道了太多的东西)
另一种做法就是用三个线程 即UI线程本身 工作线程 以及监听线程 监听线程实时获取工作线程的执行的情况 并负责更新UI 这里面有一个很大的问题就是如何实时获取工作线程的进度情况 如果不能用委托 这里就提出一种没有被验证是否可靠的但是现在来说算是可行的方案 即引用类型参数
由于引用类型参数在传值的时候传递的是本身 因此所有针对他的变化都可以被外部获取 但是为了保证该变量的安全 设计的时候将该变量作为控件 的私有字段 并对外开放只读属性 这样就保证了该变量不会被非工作线程所改变
先上调用代码 来看下我们的进度条的接口 从调用方来看十分简单
private void Start_Click(object sender, EventArgs e)
{
this.myProcessBar1.Task = this.Task;
this.myProcessBar1.Run();//开始工作线程 同时开始监听工作进度
}
//某个耗时操作 参数即当前进度
public void Task(ref float percentage)
{
int i = 0;
while (i < int.MaxValue )
{
i++;
percentage = i / (float)int.MaxValue;
}
}
private void button1_Click(object sender, EventArgs e)
{
this.myProcessBar1.Stop();//暂停进度条 同时也暂停工作线程
}
private void button2_Click(object sender, EventArgs e)
{
this.myProcessBar1.Resume();//继续进度条 同时继续工作线程
}
private void button3_Click(object sender, EventArgs e)
{
this.myProcessBar1.Abort();//终止工作进程
}
private void button4_Click(object sender, EventArgs e)
{
this.myProcessBar1.Run();//这边位重新启动进度条
}
下面是进度条本身的代码 这边用一个picturebox作为进度条容器
public partial class M