winform BackgroundWorker 的用法 - 异步执行
1.设置
backgroundWorker1.WorkerReportsProgress = true; backgroundWorker1.WorkerSupportsCancellation = true;
2说明:
开始函数:
(1) backgroundWorker1.RunWorkerAsync(参数a),触发DoWork事件,见参数a传给事件的DoWorkEventArgs参数(用e.Argument接收参数)。
在dowork事件中进行函数体操作,在实践中用ReportProgress(参数1,或者参数2)方法,将会触发ProgressChanged事件
(2)在ProgressChanged事件中,ProgressChangedEventArgs参数可以接收ReportProgress()方法的两个参数,然后进行相应的操作
(3)无论是中止还是终止BackgroundWorker线程。都会执行RunWorkerCompleted事件。
(4)所以,事件的顺序是 backgroundWorker1.RunWorkerAsync(参数a)-->DoWork事件-->ProgressChanged事件-->RunWorkerCompleted事件.
3中止BackgroundWorker
用 backgroundWorker1.CancelAsync()方法,但是此时并没有中止线程,只是将backgroundWorker1.CancellationPending改为true。此时需要在执行的事件中来判断backgroundWorker1.CancellationPending的值进行终止操作。
4案例
using System; using System.ComponentModel; using System.Threading; using System.Windows.Forms; namespace WindowsFormsApp27 { public partial class Form1 : Form { public Form1() { InitializeComponent(); Control.CheckForIllegalCrossThreadCalls = false; } private void Form1_Load(object sender, EventArgs e) { listView1.FullRowSelect = true; listView1.GridLines = true; listView1.Columns.Add("num"); listView1.Columns.Add("name"); listView1.Columns.Add("age"); listView1.Columns.Add("sex"); backgroundWorker1.WorkerReportsProgress = true; backgroundWorker1.WorkerSupportsCancellation = true; } public delegate void ShowList(int a); private void button1_Click(object sender, EventArgs e) { int num= string.IsNullOrEmpty(textBox1.Text) ? 5 : int.Parse(textBox1.Text); ; progressBar1.Maximum = num; button1.Enabled = false; backgroundWorker1.RunWorkerAsync(num);//引发backgroundWorker1_DoWork_1事件,将参数num以DoWorkEventArgs形式传给事件 } private void ADD(object nm) { int num = int.Parse(nm.ToString()); for (int i = 0; i < num; i++) { ListViewItem li = new ListViewItem() { Text = i.ToString() }; li.SubItems.Add("name" + i); li.SubItems.Add("age" + i); li.SubItems.Add("sex" + i); listView1.Items.Add(li); } } private void backgroundWorker1_DoWork_1(object sender, DoWorkEventArgs e) { object oo = e.Argument;//获取RunWorkerAsync()方法所传递的值 BackgroundWorker bw = sender as BackgroundWorker; int num = int.Parse(oo.ToString()); for (int i = 1; i <= num; i++) { if (bw.CancellationPending) {//判断是否要求中止线程 e.Cancel = true; break;//很重要 } ListViewItem li = new ListViewItem() { Text = i.ToString() }; li.SubItems.Add("name" + i); li.SubItems.Add("age" + i); li.SubItems.Add("sex" + i); bw.ReportProgress(i,li);//触发backgroundWorker1_ProgressChanged_1事件,将参数以ProgressChangedEventArgs格式传给事件。此处的百分数解析并不准确,自己根基实际情况进行计算 Thread.Sleep(100); } } private void backgroundWorker1_ProgressChanged_1(object sender, ProgressChangedEventArgs e) { BackgroundWorker b = sender as BackgroundWorker; ListViewItem li = e.UserState as ListViewItem;//接收ReportProgress方法的第二个参数参数值 listView1.Items.Add(li); progressBar1.Value = e.ProgressPercentage;//接收ReportProgress方法的第一个参数参数值 label1.Text = (e.ProgressPercentage*100/progressBar1.Maximum).ToString(); } //无论是中止还是终止,都执行该事件 private void backgroundWorker1_RunWorkerCompleted_1(object sender, RunWorkerCompletedEventArgs e) { if (e.Error != null) { MessageBox.Show(e.Error.ToString()); } else if (e.Cancelled) { MessageBox.Show(e.Cancelled.ToString()); } else { MessageBox.Show("ok了"); } button1.Enabled = true; } private void button2_Click(object sender, EventArgs e) { backgroundWorker1.CancelAsync();//此处并不是真正的中止线程,只是将backgroundWorker1.CancellationPending的值设置成了true,需要在dowork事件(即所进行的操作的函数体中)进行判断,再跳出函数(break)。 } } }