本文介绍如何在处理事务时使用进度条显示处理进度。
上下文背景:Form1类处理(模拟批量导入)产生会员信息数组。调用导入管理器ImportMgr类Work函数,实现批量导入会员信息,导入时显示导入进度,导入完成后将会员信息显示到列表listBox1。导入管理器ImportMgr类调用信息处理类ProcessInfo进行导入数据操作,调用进度条状态窗口类frmstatus显示导入进度。当导入数据完成时广播导入数据完成事件ImportDone。信息处理类ProcessInfo使用线程函数ImportMemberThreadFun开启实际导入数据函数ImportMember导入数据。在ImportMember函数中,每导入一条数据,会广播一次更新进度事件UpdateProgressValue。导入数据完成即广播导入数据完成事件ImportDone。下面简要介绍各个类。
首先介绍需要用到的参数结构体:
[数据结构.cs]
using System;
///
/// 导入数据线程的参数
///
public struct ImportParameter
{
///
/// 会员名称数组
///
public string[] MemberNames;
}
///
/// 处理进度数值参数
///
public class ProcessEventArgs : EventArgs
{
///
/// 进度数值
///
public int Value;
}
///
/// (导入数据完成时的用到的)数据参数
///
public class ImportEventArgs : EventArgs
{
///
/// 数据数组
///
public string[] datas;
}
ImportaParameter是批量导入线程用到的数据参数。ProgressBarEventArgs是进度变更事件的数值参数。ImportEventArgs是导入数据完成事件用到的数据参数。
然后是主窗体类[
Form1.cs]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace 进度条显示处理进度
{
public partial class Form1 : Form
{
#region 本地变量
///
/// 导入管理器实例
///
ImportMgr mgr;
#endregion
#region 构造函数
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
mgr = new ImportMgr();
//绑定导入数据操作完成要执行的函数
mgr.ImportDone+=new EventHandler(Mgr_ImportDone);
}
#endregion
#region 功能函数
//导入管理器导入操作完成后调用的函数
private void Mgr_ImportDone(object sender, EventArgs e)
{
//参数类型转换
ImportEventArgs ie = (ImportEventArgs)e;
//加载数据到控件
this.ListBoxAddDatas(ie.datas);
}
//测试1
private void F测试1()
{
ImportParameter para = new ImportParameter();//传入到线程内的参数
//假定有100名会员
para.MemberNames = new string[100];
for (int i = 0; i < 100; i++)
{
para.MemberNames[i] = "机器人"+(i+1).ToString();
}
mgr.Work(para);//导入管理器开始工作:导入会员数据
}
//加载数据到控件的委托
public delegate void AddDatasDelegate(string[] datas);
//加载数据到控件
public void ListBoxAddDatas(string[] datas)
{
//外部线程加载数据的操作请求
if (listBox1.InvokeRequired)
{
AddDatasDelegate d = new AddDatasDelegate(ListBoxAddDatas);
listBox1.Invoke(d, new object[] { datas });
}
else //(本线程内)控件加载数据
{
this.AddDatas(datas);
}
}
//(本线程内)控件加载数据
private void AddDatas(string[] datas)
{
foreach (string t in datas)
{
this.listBox1.Items.Add(t);
}
}
#endregion
#region 事件响应
private void btn_测试_Click(object sender, EventArgs e)
{
this.F测试1();
}
#endregion
}
}
然后是处理信息的类
[ProcessInfo.cs]
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace 进度条显示处理进度
{
///
/// 处理信息类
///
public class ProcessInfo
{
public ProcessInfo()
{
}
#region 处理信息--业务逻辑端
///
/// 更新进度信息事件
///
public event EventHandler UpdateProgressValue;
///
/// 导入数据完成事件
///
public event EventHandler ImportDone;
///
/// 线程函数(此例中线程操作为为导入会员)
///
/// 会员信息集
public void ImportMemberThreadFun(object msg)
{
Thread importMemberThread = new Thread(new ParameterizedThreadStart(ImportMember));
importMemberThread.Start(msg);
}
///
/// 线程实际操作函数(导入会员信息)
///
private void ImportMember(object msg)
{
ImportParameter para = (ImportParameter)msg;//线程参数:所导入会员数据
ImportEventArgs importDatas = new ImportEventArgs();
double t=0;
try
{
importDatas.datas = new string[para.MemberNames.Length];
for (int i = 0; i < para.MemberNames.Length; i++)
{
//处理进度数值参数
ProcessEventArgs pe = new ProcessEventArgs();
t = 100 * (i + 1) / para.MemberNames.Length;//算出处理进度
pe.Value = (int)Math.Floor(t);//进度值向下取整
importDatas.datas[i] = para.MemberNames[i];//在此就算导入数据了(模拟)
this.UpdateProgressValue(this, pe); //更新进度
Thread.Sleep(50); //模拟导入数据耗时
}
}
catch (Exception ex)
{
throw ex;
}
//广播导入完成事件
this.ImportDone(this, importDatas);
}
#endregion
}
}
UpdateProgressValue是变更进度信息事件,ImportMemberThreadFun是线程函数,ImportMember是线程函数调用的实际处理信息的函数,该函数每处理完一条信息都会触发一次。
然后是进度条状态窗体
[frmstatus.cs]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace 进度条显示处理进度
{
public partial class frmStatus : Form
{
///
/// 进度完成进度完成
///
private bool workDone = false;
///
/// 显示信息
///
public string Message = string.Empty;
//构造函数
public frmStatus()
{
InitializeComponent();
}
///
/// 设置进度条进度值委托
///
/// 进度值
public delegate void SetProgressValueDelegate(int value);
///
/// (创建本控件的线程)设置进度条数值
///
/// 进度条数值
private void SetValue(int value)
{
this.progressBar1.Value = value;
this.lblStatus.Text = this.Message
+ Environment.NewLine
+ Environment.NewLine
+ " 进度 :" + value.ToString() + "%";
if (value == this.progressBar1.Maximum)
{
this.Message = " 操作已完成!";
this.lblStatus.Text = this.Message
+ Environment.NewLine + Environment.NewLine
+ " 进度 :" + value.ToString() + "%";
workDone = true;
}
if (workDone)
{
this.btn_close.Visible = true;
}
}
//设置进度条进度值
///
/// 设置进度条进度值
///
/// 进度值
public void SetProgressValue(int value)
{
//外部线程设定进度值的操作请求
if (this.InvokeRequired)
{
SetProgressValueDelegate d = new SetProgressValueDelegate(SetProgressValue);
this.Invoke(d, new object[] { value });
}
else //(本线程内)设定进度值
{
this.SetValue(value);
}
}
private void btn_close_Click(object sender, EventArgs e)
{
this.Visible = false;
}
}
}
SetProgressValue是外部请求设置进度值的函数,SetValue是创建本控件类内部实际设置进度值的函数。SetProgressValueDelegate是设置进度条进度值委托。
然后是导入管理器
[ImportMgr.cs]
using System;
using System.Collections.Generic;
using System.Text;
namespace 进度条显示处理进度
{
///
/// 导入管理器
///
public class ImportMgr
{
///
/// 进度条状态窗口
///
frmStatus frmStatusMessage;
///
/// 导入数据完成事件
///
public event EventHandler ImportDone;
///
/// 处理信息对象
///
ProcessInfo processer;
string[] nameDatas;
public ImportMgr()
{
frmStatusMessage = new frmStatus();//初始化状态窗口
processer = new ProcessInfo();//初始化处理信息对象
//订阅处理信息状态事件
processer.UpdateProgressValue += new EventHandler(ImportMgr_UpdateProgressValue);
//绑定导入数据操作完成要执行的函数
processer.ImportDone +=new EventHandler(Processer_ImportDone);
}
//更新进度信息事件,processer.UpdateProgressValue每广播一次就调用此函数
private void ImportMgr_UpdateProgressValue(object sender, EventArgs e)
{
ProcessEventArgs se = (ProcessEventArgs)e;
frmStatusMessage.SetProgressValue(se.Value);//请求设定进度值
}
//广播导入数据完成事件(并传出所导入的数据)
private void Processer_ImportDone(object sender, EventArgs e)
{
ImportEventArgs ie = (ImportEventArgs)e;
nameDatas = ie.datas; ;
this.ImportDone(this, ie);
}
///
/// 工作:导入会员数据
///
/// 参数:会员数据
public void Work(ImportParameter p)
{
processer.ImportMemberThreadFun(p);//调用启动线程函数,导入会员名称数据
frmStatusMessage.Show();//显示进度条窗口
}
}
}
导入管理器包含了进度条显示窗口frmStatusMessage、处理信息对象processer。成员函数Work即导入操作的实际工作函数。导入管理器导入完数据会广播导入数据完成事件ImportDone。