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

C# 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裏面儲存URL
backgroundWorker1.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函數,用來引發事件ProgressChanged
worker.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;
}
else
MessageBox.Show("操作成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}

來自: http://hi.baidu.com/bendi160/blog/item/5fd2ce25ce21e00c4d088dcd.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章