通用进度条的设计与实现【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。
相关文章推荐
- iOS开发:代码通用性以及其规范 第二篇(猜想iOS中实现TableView内部设计思路(附代码),以类似的思想实现一个通用的进度条)
- C#PDA智能程序图片动态变化进度条设计及实现
- Java 和 C#通用的DES加密工具类的实现
- 设计模式的C#实现
- 用c#实现通用守护进程
- 《游戏设计、原型与开发——基于Unity与C#从构思到实现》学习笔记一
- 设计模式之C#实现(三)FactoryMethod
- 数据结构课程设计-----用C#实现双向链表
- 设计模式C#实现(六)——单例模式
- 基于STM32的学习型通用红外遥控设备的设计实现(三)
- Socket通用TCP通信协议设计及实现(防止粘包,可移植,可靠)
- 基于 IOCP 的通用异步 Windows Socket TCP 高性能服务端组件的设计与实现
- 通用编程训练-C#延迟赋值函数的实现
- 一个通用的单元测试框架的思考和设计06-实现篇-自动管理测试数据-如何临时关闭数据外键约束
- 一个.NET通用JSON解析/构建类的实现(c#)(转载)
- C# 设计模式学习四 Builder生成器模式(关于映射实现补充)
- 通用的业务编码规则设计实现
- 设计、实现一个 Asp.Net 应用的通用数据存取层
- singleton设计模式的C#实现(上)
- C#小练习(设计一个程序,输入10个数存入数组中,然后实现冒泡排序。 )