首先,通用进度条类的实现
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。