非常实用的C# backgroundworker使用方法

    技术2025-02-17  18

    # BackgroundWorker 控件的几个实例(C# backgroundworker使用方法):

    在 WinForms 中,有时要执行耗时的操作,在该操作未完成之前操作用户界面,会导致用户界面停止响应。解决的方法就是新开一个线程,把耗时的操作放到线程中执行,这样就可以在用户界面上进行其它操作。新建线程可以用 Thread 类,可以实现多线程同时操作,简单的可以通过 BackgroundWorker 类实现。用 BackgroundWorker 类执行耗时的操作BackgroundWorker 类在 System.ComponentModel 命名空间下。VS 的工具箱时有一个 BackgroundWorker 组件,就是这个类。

    常用方法1.RunWorkerAsync开始执行后台操作。引发 DoWork 事件2.CancelAsync请求取消挂起的后台操作。注意:这个方法是将 CancellationPending 属性设置为 true,并不会终止后台操作。在后台操作中要检查 CancellationPending 属性,来决定是否要继续执行耗时的操作。

    3.ReportProgress引发 ProgressChanged 事件。常用属性1.CancellationPending指示应用程序是否已请求取消后台操作。只读属性,默认为 false,当执行了 CancelAsync 方法后,值为 true。

    2.WorkerSupportsCancellation指示是否支持异步取消。要执行 CancelAsync 方法,需要先设置该属性为 true。3.WorkerReportsProgress指示是否能报告进度。要执行 ReportProgress 方法,需要先设置该属性为 true。

     

    常用事件1.DoWork调用 RunWorkerAsync 方法时发生。2.RunWorkerCompleted后台操作已完成、被取消或引发异常时发生。

    3.ProgressChanged调用 ReportProgress 方法时发生。

     

    在 DoWork 事件处理程序中不操作任何用户界面对象。而应该通过 ProgressChanged 和 RunWorkerCompleted 事件与用户界面进行通信。

    如果想在 DoWork 事件处理程序中和用户界面的控件通信,可在用 ReportProgress 方法。ReportProgress(int percentProgress, object userState),可以传递一个对象。

    ProgressChanged 事件可以从参数 ProgressChangedEventArgs 类的 UserState 属性得到这个信息对象。简单的程序用 BackgroundWorker 比 Thread 方便,Thread 中和用户界面上的控件通信比较麻烦,需要用委托来调用控件的 Invoke 或 BeginInvoke 方法,没有 BackgroundWorker 方便。

    ============================

    一个简单的刷网页流量的小工具代码

    1. 从工具栏拖一个BackgroundWorker控件,设置其属性WorkerReportsProgress为true

    2. 要让worker开始工作,执行如下代码:mBackgroundWorker.RunWorkerAsync(arg);这里有重写,如果不需要传递参数直接mBackgroundWorker.RunWorkerAsync();

    3. 编辑DoWork事件代码:e.Argument为mBackgroundWorker.RunWorkerAsync(arg);对应的参数之所以使用进度条,肯定是有循环的,在循环中报告进度:worker.ReportProgress(i * 100 / totalNum, obj );其中第一个参数是当前进度的百分之多少,obj为你要传递的UserState,如果没有可以不要

    4. 编辑ProgressChanged事件代码:e.ProgressPercentage为进度的百分数,e.UserState为刚才传递过来的object在这个事件中可以调用ui的进度条和其他控件:mToolStripProgressBar.Value = e.ProgressPercentage;

    5. 编辑RunWorkerCompleted事件代码:工作完成了告诉ui

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.Net;using System.Threading;

    namespace WindowsApplication15{public partial class Form1 : Form{public Form1(){InitializeComponent();}

    private void button1_Click(object sender, EventArgs e){//textBox1.Text里面储存URLbackgroundWorker1.RunWorkerAsync(textBox1.Text);}

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e){BackgroundWorker bw = (BackgroundWorker)sender;string url = e.Argument.ToString();

    for (int i = 0; i < 10; i++){//没有取消后台操作if (!bw.CancellationPending){WebRequest req = WebRequest.Create(url);WebResponse resp = req.GetResponse();resp.Close();

    Thread.Sleep(1000);bw.ReportProgress(i * 100 / 10, i);}}}

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e){progressBar1.Value = e.ProgressPercentage;label1.Text = e.UserState.ToString();}

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){MessageBox.Show("ok!");}}}

    ======================

    http://hi.baidu.com/yebihaigsino/blog/item/eeccbb02fdf1228fd43f7c8a.html 更高级的backgroundworker控件实例应用

    ===================

    http://blog.163.com/j_yd168/blog/static/4967972820092114269195/ c# BackGroundWorker 多线程操作的小例子

    ============ ================这个例子含数据库操作

    一、BackGroundWorker工作步骤

    1.向窗体中拖入一个BackGroundWorker控件。

    2.在某个方法或者事件中,调用BackGroundWorker的RunWorkerAsync()方法。

    3.该方法为异步操作,将自动引发BackGroundWorker的DoWork事件。

    4.调用ReportProgress方法将引发ProgressChanged事件。

    二、一个使用了BackGroundWorker的例子

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.Threading;using System.Data.SqlClient;

    //该用例需要一个名为bgwTestDB的Sql Server数据库//数据库中应包含tbBgwTest表。//表中有data1、data2两列。//数据库中还需要一个存储过程,sql语句如下:

    namespace winBackgroundWorkerTest{public partial class backgroundWorkerTest : Form{int count = 30;

    public backgroundWorkerTest(){InitializeComponent();}

    private void btnAdd_Click(object sender, EventArgs e){//1.调用bgwInsertData的RunWorkerAsync方法,用来引发DoWork事件bgwInsertData.RunWorkerAsync(count);}

    private void bgwInsertData_DoWork(object sender, DoWorkEventArgs e){BackgroundWorker worker = sender as BackgroundWorker;//2.在DoWork中调用自定义函数,并将引发DoWork事件的sender传递出去insertData(worker);}

    private void bgwInsertData_ProgressChanged(object sender, ProgressChangedEventArgs e){progressBar1.Value = e.ProgressPercentage;}

    //自定义函数 insertData()private void insertData(BackgroundWorker worker){SqlConnection conn = new SqlConnection(@"Data Source=./sqlexpress;Initial Catalog=bgwTestDB;Integrated Security=True");

    SqlCommand cmd = new SqlCommand("insertOneData", conn);cmd.CommandType = CommandType.StoredProcedure;cmd.Parameters.Add("data1", SqlDbType.NChar, 10);cmd.Parameters.Add("data2", SqlDbType.Int);

    for (int i = 0; i < count; i++){try{conn.Open();cmd.Parameters["data1"].Value = i + 1;cmd.Parameters["data2"].Value = i + 1;cmd.ExecuteNonQuery();

    //3.调用worker的ReportProgress函数,用来引发事件ProgressChangedworker.ReportProgress(i, worker);}catch (Exception ex){MessageBox.Show(ex.Message);}finally{if (conn.State == ConnectionState.Open)conn.Close();}

    Thread.Sleep(50);}}

    private void bgwInsertData_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){if (e.Error != null){MessageBox.Show(e.Error.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);return;}else if (e.Cancelled){MessageBox.Show("取消操作!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);return;}elseMessageBox.Show("操作成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);}}}

    最新回复(0)