多线程:C#.NET中使用BackgroundWorker在模态对话框中显示进度条

我们使用C#.NET编写WinForm程序时,有时候为了实现在模态对话框中实时显示后台操作的进度,这个时候需要借助于多线程操作在子窗体中显示进度条状态,在父窗体中进行后台操作。你可以在Thread类中自己创建两个线程以完成这个操作,不过C#.NET提供了BackgroundWorker对象可以帮助我们非常方便地来实现这个过程。有关Backgroundworker对象的时候我在“C#遍历文件读取Word内容以及实用BackgroundWoker对象打造平滑进度条”一文中有过介绍,大家可以去看看。
这里是一个示例,其中展示了如何使用Backgroundworker对象在模态对话框中显示后台操作的实时进度条。
首先是主窗体代码:
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.Threading; 10 11 namespace ModalProgressDialog 12 { 13 public partial class Form1 : Form 14 { 15 protected BackgroundWorker worker = new BackgroundWorker(); 16 protected Form2 frm = new Form2(); 17 18 public Form1() 19 { 20 InitializeComponent(); 21 } 22 23 private void button1_Click(object sender, EventArgs e) 24 { 25 worker.WorkerReportsProgress = true; 26 27 worker.DoWork += new DoWorkEventHandler(worker_DoWork); 28 worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged); 29 worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); 30 worker.RunWorkerAsync(); 31 frm.ShowDialog(); 32 } 33 34 void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 35 { 36 frm.Close(); 37 MessageBox.Show("Done"); 38 } 39 40 void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) 41 { 42 frm.ProgressValue = e.ProgressPercentage; 43 } 44 45 void worker_DoWork(object sender, DoWorkEventArgs e) 46 { 47 CountTheTime(); 48 } 49 50 private void CountTheTime() 51 { 52 int initialValue = 100; 53 for (int count = 0; count < initialValue; count = count + 2) 54 { 55 Thread.Sleep(1000); 56 worker.ReportProgress(count); 57 } 58 } 59 } 60 }
主窗体中只有一个按钮,当被点击时,会由BackgroundWorker对象以异步的方式去执行一个假象的后台操作CountTheTime方法。CountTheTime方法从0到100以步长为2每隔1秒更新一下进度条状态,因此这个假象的后台操作大约会持续50秒左右的时间。当程序执行时,进度条指示窗口以模态对话框的形式被弹出,然后实时显示后台操作的进度。
BackgroundWorker对象有三个主要的事件:
DoWork - 当BackgroundWorker对象的多线程操作被执行时触发。
RunWokerCompleted - 当BackgroundWoker对象的多线程操作完成时触发。
ProgressChanged - 当BackgroundWorker对象的多线程操作状态改变时触发。
另外还有一个非常重要的属性WorkerReportsProgress - 如果想让BackgroundWorker对象以异步的方式报告线程实时进度,必须将该属性的值设为true。
BackgroundWorker对象的ReportProgress方法用于向主线程返回后台线程执行的实时进度。
下面是子窗体的代码:
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 10 namespace ModalProgressDialog 11 { 12 public partial class Form2 : Form 13 { 14 public int ProgressValue 15 { 16 get { return this.progressBar1.Value; } 17 set { progressBar1.Value = value; } 18 } 19 20 public Form2() 21 { 22 InitializeComponent(); 23 } 24 } 25 }
子窗体中放置了一个ProgressBar控件,对外可以通过ProgressValue属性来获取和修改进度条的当前值。同时,我们可以将子窗体的FormBorderStyle属性设为FixedDialog以使其看起来更像对话框,然后将MaximizeBoxMinimizeBox都设为false,将ControlBox属性设为false以隐藏窗体关闭按钮。在父窗体中,我们通过BackgroundWorker对象的RunWorkerAsync方法触发DoWork事件,此时CountTheTime()方法被执行。在CountTheTime()方法中,通过ReportProgress()方法从后台进程(父窗体)传递进度指示到主UI线程(子窗体)中,这样同时会触发ProgressChanged事件,然后我们在该事件中更新子窗体的进度条状态。下面是程序执行时的截图。
多线程:C#.NET中使用BackgroundWorker在模态对话框中显示进度条
Tags: 

延伸阅读

最新评论

发表评论