BackgroundWorder控件:
BackgroundWorker控件顾名思义,是执行后台工作的控件,准确来说,是在非主线程上执行操作的控件。该类型定义在System.ComponentModel命名空间,该控件的使用非常简单,只要在工具库中把该控件拖动到界面就可以了。
比较重要的属性:
CancellationPending:只读属性,表示应用程序是否已经取消后台操作
IsBuys:只读属性,表示控件是否正在进行异步操作。
WorkerReportsProgress:表示该控件能否报告进度更新
WorkerSupportsCancellation:表示该控件是否支持取消异步操作
比较常用的方法:
CancelAsync():取消异步操作
OnDoWork(DoWorkEventArgs):引发DoWork事件,实际上这是控件开始执行的标志
OnProgressChanged(ProgressChangedEventArgs):
ReportProgress():
ReportProgress(Int32):以上三个方法都出发ProgressChanged事件。
RunWorkerAsync():
RunWorkerAsync(Object):开始执行操作。
OnRunWorkerCompleted(RunWorkerCompleteEventArgs):引发RunWorkerCompleted事件。
主要方法就这些,上面说到的所有方法其实都会引发事件,下面介绍该控件的三个主要事件
DoWork事件:调用RunWorkerAsync()、RunWorkerAsync(Object)、OnDoWork(DoWorkEventArgs)方法都会触发该事件,该事件里边要放需要异步执行的操作。
ProgressChanged事件:调用OnProgressChanged(ProgressChangedEventArgs)、ReportProgress(Int32)、ReportProgress(Int32)都会触发该事件,该事件主要用来获取异步执行操作的反馈信息。
RunWorkerCompleted事件:CancelAsync()、OnRunWorkerCompleted、异步执行过程出现异常或则执行完成后都会调用该事件。
下面是一个例子,该例子只有一个需求,就是向DataGridView中添加数据,当我们需要添加大量的数据时,可以考虑将添加数据的过程放到BackgroundWorder控件的DoWork事件中,下面是客户端的截图
代码如下:
public partial class Form1 : Form { DataTable dataTabe = new DataTable(); Random random = new Random(); String[] sexs = new String[2] { "Man", "Women" }; public Form1() { InitializeComponent(); } private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { UInt64 count = (UInt64)e.Argument; UInt64 index = 0; Console.WriteLine(DateTime.Now.ToLongTimeString()); Console.WriteLine(DateTime.Now.Millisecond); while (index < count) { DataRow row = dataTabe.NewRow(); row["ID"] = (index + 1).ToString(); row["Name"] = String.Format("Name{0}", index + 1); row["Year"] = random.Next(10, 50); row["Sex"] = sexs[random.Next(0, 2)]; row["Price"] = (random.NextDouble() * 1000).ToString("f2"); row["Num"] = random.Next(100, 300); row["Date"] = String.Format("201{0}-{1}-{2}", random.Next(0, 7), random.Next(1, 13), random.Next(1, 28)); dataTabe.Rows.Add(row); index++; } Console.WriteLine(DateTime.Now.ToLongTimeString()); Console.WriteLine(DateTime.Now.Millisecond); //dataTabe.Rows.Clear(); //for (index = 0; index < count; index++) //{ // DataRow row = dataTabe.NewRow(); // row["ID"] = (index + 1).ToString(); // row["Name"] = String.Format("Name{0}", index + 1); // row["Year"] = random.Next(10, 50); // row["Sex"] = sexs[random.Next(0, 2)]; // row["Price"] = (random.NextDouble() * 1000).ToString("f2"); // row["Num"] = random.Next(100, 300); // row["Date"] = String.Format("201{0}-{1}-{2}", random.Next(0, 7), random.Next(1, 13), random.Next(1, 28)); // dataTabe.Rows.Add(row); //} //Console.WriteLine(DateTime.Now.ToLongTimeString()); //Console.WriteLine(DateTime.Now.Millisecond); } private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { } private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { dataGridView1.DataSource = new DataView(dataTabe); } private void button1_Click(object sender, EventArgs e) { UInt64 count = 0; if (string.IsNullOrEmpty(textBox1.Text)) { MessageBox.Show("Pleasr input the num of data."); } else if (!UInt64.TryParse(textBox1.Text,out count)) { MessageBox.Show("The num of data is invalid."); } else { backgroundWorker.RunWorkerAsync(count); } } private void button2_Click(object sender, EventArgs e) { dataGridView1.DataSource = null; } private void Form1_Load(object sender, EventArgs e) { dataGridView1.AutoGenerateColumns = false; try { foreach (DataGridViewColumn column in dataGridView1.Columns) { DataColumn col = new DataColumn(); column.DataPropertyName = column.Name; col.DataType = typeof(String); col.ColumnName = column.Name; dataTabe.Columns.Add(col); } } catch (Exception) { } }
但是从我目前了解的知识来看,该控件和我另一起个线程来执行其实是一样的,如果非要找一点
BackgroundWorder控件的优势来说就是他可以方便的利用ProgressChanged事件切回到主线程执行操作。
注明:关于BackgroundWorder控件的属性事件说明参考MSDN,具体地址https://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker.aspx
本人也是刚刚学习BackgroundWorder控件,有没说明白或者错误的地方请指正,我以后有发现不合理的地方也会再次更新。