您的位置:首页 > 编程语言 > C#

通用进度条的设计与实现【C#】

2008-07-28 12:23 357 查看
首先,通用进度条类的实现
public partial class ProgressShow : Form
{
#region 变量、属性
///
/// 窗口的返回值
///
private DialogResult _dialogResult;
///
/// 事件处理线程
///
private Thread _handleThread;
///
/// 进程处理接口
///
private IProgressBar _progressBar;
private bool ifSucceed = false;
private bool isInProgress = false;
#endregion

#region 代理
private delegate void _setProgressBar(System.Windows.Forms.ProgressBar pgb, int value);
private delegate void _setLabelText(System.Windows.Forms.Label lb, string text);
#endregion

#region 构造方法
public ProgressShow()
{
InitializeComponent();
}

public ProgressShow(IProgressBar progressBar)
{
this._progressBar = progressBar;
InitializeComponent();
}
#endregion

///
/// 线程处理方法
///
private void HandleThreadProc()
{
try
{
bool threadFlag = true;
isInProgress = true;
while (threadFlag)
{
ifSucceed = this._progressBar.ProgressMethod();
isInProgress = false;
threadFlag = false;
}
//退出线程
_handleThread.Abort();
}
catch (Exception ex)
{
_handleThread = null;
System.Console.WriteLine(ex.Message);
}
finally
{
//设置进度条状态
if (ifSucceed)
{
SetLabelText(lbInfo, "处理事件已完成");
}

SetProgressBarValue(pgbar, pgbar.Maximum - 1);
SetLabelText(lbProgress, "99%");
}
}

#region 设置Label的方法
///
/// 设置Label状态
///
///
///
private void SetLabelText(System.Windows.Forms.Label lb, string text)
{
try
{
if (lb.InvokeRequired)
{
_setLabelText d = new _setLabelText(SetLabelTextInvoke);
lb.Invoke(d, new object[] { lb, text });
}
else
{
SetLabelTextInvoke(lb, text);
}
}
catch
{

}
}

private void SetLabelTextInvoke(System.Windows.Forms.Label lb, string text)
{
lb.Text = text;
}
#endregion

#region 进度条设置方法
///
/// 设置进度条
///
///
///
private void SetProgressBarValue(System.Windows.Forms.ProgressBar pgb, int value)
{
try
{
if (pgb.InvokeRequired)
{
_setProgressBar d = new _setProgressBar(SetProgressBarValueInvoke);
this.Invoke(d, new object[] { pgb, value });
}
else
{
this.SetProgressBarValueInvoke(pgb, value);
}
}
catch (Exception ex)
{
throw ex;
}
}

private void SetProgressBarValueInvoke(System.Windows.Forms.ProgressBar pgb, int value)
{
pgb.Value = value;
}
#endregion

///
/// 定时器,用于处理进度条
///
///
///
private void timerProgress_Tick(object sender, EventArgs e)
{
if (pgbar.Value == pgbar.Maximum)
{
//是否在运行中
if (this.isInProgress)
{
pgbar.Value = 0;
}
else
{
timerProgress.Stop();
if (ifSucceed)
{
_dialogResult = DialogResult.OK;
this.Close();
}
else
{
_dialogResult = DialogResult.Cancel;
this.Close();
}
}
}
else
{
pgbar.Increment(1);
//进度显示
this.lbProgress.Text = Math.Floor(Convert.ToDouble(pgbar.Value * 100 / pgbar.Maximum)).ToString() + "%";
}
}

///
/// Form初始化方法
///
///
///
private void ProgressShow_Load(object sender, EventArgs e)
{
timerProgress.Start();
_handleThread = new Thread(new ThreadStart(HandleThreadProc));
_handleThread.Start();
}

///
/// 窗口关闭时调用的方法
///
///
///
private void ProgressShow_FormClosed(object sender, FormClosedEventArgs e)
{
this.DialogResult = this._dialogResult;
}
}
说明
1、由于本进度条类要处理界面显示以及相应的业务方法(该方法依据不同的业务需求可以随时变化,只要相应的业务类继承接口IProgressBar实现接口方法即可),并且这两个工作要并行进行,因此程序开启了一个新的处理业务方法的线程,而界面显示的处理由Timer事件去处理
2、因为本进度条为通用进度条,我们并不知道以后要处理什么样的业务方法,这种情况下我们有两种选择来处理。
其一,使用代理机制,客户将业务方法传入,在通用进度条类中使用该代理,从而调用这个外部可变的业务方法。
其二,使用接口,在继承该接口的类对象中实现接口方法,也就是业务方法。并且将接口传入,通过调用接口方法来调用外部的业务方法。
由于我们需要一些必须的变量,只通过参数记录有些笨拙,因此最后选择了第二种方法——接口

其次,IProgressBar接口:

public interface IProgressBar
{
///
/// 用来处理业务的方法
///
///
bool ProgressMethod();
}
第三,通过删除文件操作予以说明:
public class DeleteLogFile : IProgressBar
{
//private string tempdirectory;
//private DateTime dtBefore;
private object[] _para;
///
/// 操作类别
///
private Type _type;

#region 构造方法
///
/// 构造方法
///
/// 操作类别(0-压缩数据库;1-删除数据库过期记录;2-删除日志文件)
/// 参数列表
public DeleteLogFile(Type type, params object[] args)
{
this._type = type;
this._para = args;
}
#endregion

public bool ProgressMethod()
{
switch (this._type)
{
case Type.LogFile:
string tempdirectory = (string)_para[0];
DateTime dtBefore = (DateTime)_para[2];
//首先删除日志,判断其是否删除成功
if (DeleteTempFiles(tempdirectory, dtBefore))
{
tempdirectory = (string)_para[1];
return DeleteTempFiles(tempdirectory, dtBefore);//日志删除成功后,删除临时文件
}
else
{
return false;
}
case Type.Report:
int limit = (int)_para[0];
return DeleteDBReport(limit);
case Type.Compression:
return CompressionDBFile();
default:
return false;
}
}

///
/// 删除指定日期以前的过期文件夹,子文件夹和文件
///
/// 目标目录
/// 过期时间
private bool DeleteTempFiles(string tempdirectory, DateTime dtBefore)
{
bool retBool = false;
try
{
if (Directory.Exists(tempdirectory))
{
string[] files = Directory.GetFileSystemEntries(tempdirectory);

//得到目标目录下所有文件及文件夹信息
foreach (string d in files)
{
if (File.Exists(d))
{
//直接删除其中的文件
if (File.GetCreationTime(d) < dtBefore || dtBefore.Equals(DateTime.MinValue))
File.Delete(d);
}
else
{
//递归删除子文件夹
DeleteTempFiles(d, dtBefore);
}
}
}
retBool = true;
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
return retBool;
}

private bool DeleteDBReport(int limit)
{
bool result = false;
SqlParameter para0, para1;
List lstPara = new List();
//定义参数值
try
{
#region 调用删除过期批次的存储过程
//时间间隔
para0 = new SqlParameter("@LIMIT", SqlDbType.Int);
para0.Value = limit;
lstPara.Add(para0);
//结束过期批次
DBBean.dbBean.executeQuery("SP_UPDATE_BATCH_AUTOEND", lstPara);
//删除过期的批次所有相关信息
para1 = new SqlParameter("@TYPE", SqlDbType.Int);
para1.Value = 0;
lstPara.Add(para1);
DBBean.dbBean.executeQuery("SP_DELETE_HISTORYINFO", lstPara);
result = true;
#endregion
}
catch (SqlException ex)
{
result = false;
}
finally
{
DBBean.dbBean.close();
}
return result;
}

private bool CompressionDBFile()
{
bool result = false;
try
{
DBBean.dbBean.setTimeout(300);
//清空日至
string sqlString = "BACKUP TRANSACTION BARCODEPRINTER WITH  NO_LOG";
DBBean.dbBean.executeScalar(sqlString);

//截断事务日至
sqlString = "BACKUP LOG BARCODEPRINTER WITH NO_LOG";
DBBean.dbBean.executeScalar(sqlString);

sqlString = "USE [BARCODEPRINTER];"
+ "DBCC SHRINKDATABASE(BARCODEPRINTER)";
DBBean.dbBean.executeScalar(sqlString);
sqlString = "USE MASTER";
DBBean.dbBean.executeScalar(sqlString);

result = true;
}
catch (Exception)
{
result = false;
}
finally
{
DBBean.dbBean.close();
}
return result;
}
}
最后,通用进度条的使用
IProgressBar progressBar = new DeleteLogFile(Type.Compression);
ProgressShow pro = new ProgressShow(progressBar);
if (pro.ShowDialog() == DialogResult.OK)
{
MessageBox.Show("压缩成功!");
重置当前的数据库空间大小
ResetDBText();
}
else
{
MessageBox.Show("操作失败...请稍后重试");
}

//说明: 想要使用通用进度条的用户首先要实现IProgressBar接口,以该接口对象构造出ProgressShow对象。
//而IProgressBar接口中的bool ProgressMethod()方法用于处理相应的业务逻辑。例如要删除某路径的文件,
//则可以在实现该接口的类中相应方法内些相应的删除文件方法,当全部删除完成时,返回true。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: