winform BackgroundWorker的使用

Posted 王炜忠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)。

        }
    }
}
View Code

完!

 

以上是关于winform BackgroundWorker的使用的主要内容,如果未能解决你的问题,请参考以下文章

winform异步系统升级—BackgroundWorker

如果我不在 WinForms 上使用 Thread.Sleep,BackgroundWorker 将不起作用

是否可以在没有 BackgroundWorker 的情况下使 WinForms 响应? [关闭]

将 'BackgroundWorker' 替换为 'Thread'

C# backgroundworker使用方法

c# winForm开发的一个异常问题,异常描述是:"调用的目标发生了异常问题"