SauronKing

写随笔只是为了记录自己的曾经,如果能给您带来些许方便,那是我莫大的荣幸!

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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事件中,下面是客户端的截图

image

代码如下:

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控件,有没说明白或者错误的地方请指正,我以后有发现不合理的地方也会再次更新。

posted on 2016-05-13 20:14  SauronKing  阅读(543)  评论(0编辑  收藏  举报