最近出去玩,照了好多照片,想传到我的人人去,发现照片太大,传起来老费劲了。
于是写了这个《批量照片缩小器》,顺带回忆一下BackgroundWorker这个后台工作控件的使用。
界面如上,很简单不多说。效果图如下:
(原始图片)
(缩小后)
使用BackgroundWorker的步骤:
1. 拖拽一个BackgroundWorker控件出来
2. 设置其属性
设置WorkerReportsProgress和WorkerSupportsCancellation属性都为true
3. 生成事件代码
点击闪电按钮( ),分别双击三个事件项目,生成三个事件代码
4. 编写后台工作事件
worker_DoWork
1 private void worker_DoWork(object sender, DoWorkEventArgs e) 2 { 3 var param = e.Argument as ZoomData; 4 var photoDir = new DirectoryInfo(param.photoDir); 5 var files = photoDir.GetFiles(); 6 var userState = new ReportData() { all = files.Count(), done = 0 }; 7 worker.ReportProgress(userState.done, userState); 8 foreach (var pic in files) 9 {10 try11 {12 userState.done++;13 worker.ReportProgress(userState.done, userState);14 var img = Image.FromFile(pic.FullName);//若不是图片,此处会报错,我就不用分析了15 var width = param.percent * img.Width / 100;16 if (width <= 0) width = 1;17 var height = param.percent * img.Height / 100;18 if (height <= 0) height = 1;19 var newImage = img.GetThumbnailImage(width, height, callBack, IntPtr.Zero);20 newImage.Save(Path.Combine(param.afterDir, pic.Name));21 img.Dispose();22 newImage.Dispose();23 }24 catch (System.Exception ex)25 {26 27 }28 }29 }
worker_ProgressChanged
1 private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)2 {3 var userState = e.UserState as ReportData;4 var value = e.ProgressPercentage * 100 / userState.all;5 if (value < pgbProcess.Minimum) value = pgbProcess.Minimum;6 if (value > pgbProcess.Maximum) value = pgbProcess.Maximum;7 pgbProcess.Value = value;8 }
worker_RunWorkerCompleted
1 private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 2 { 3 if (e.Error != null) 4 { 5 MessageBox.Show(e.Error.ToString(), "发生异常"); 6 if (MessageBox.Show("是否打开保存结果的文件夹?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) 7 == DialogResult.Yes) 8 { 9 Process.Start("explorer", txtAfterDir.Text);10 }11 }12 else if (e.Cancelled)13 {14 if (MessageBox.Show("您取消了操作,是否打开保存结果的文件夹?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question)15 == DialogResult.Yes)16 {17 Process.Start("explorer", txtAfterDir.Text);18 }19 }20 else21 {22 if (MessageBox.Show("操作已完成,是否打开保存结果的文件夹?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question)23 == DialogResult.Yes)24 {25 Process.Start("explorer", txtAfterDir.Text);26 }27 pgbProcess.Value = pgbProcess.Minimum;28 //lblProgress.Text = "";29 btnStart.Text = "开始";30 }31 }
这是标准的使用后台工作控件的方法,其中的worker_DoWork是后台线程执行的方法,使用worker.ReportProgress();方法可以激发worker_ProgressChanged函数,worker_ProgressChanged是在UI线程执行的,用于修改进度条的进度,在后台线程执行完(或抛出异常或提前取消)后,会激发worker_RunWorkerCompleted函数,对执行完成的任务进行后续整理。