C#學習筆記之BackGroundWorder using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BackGroundWorder元件控件
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// BackGroundWorker是.NET裡用來執行多線程的控件,它允許程式員在單獨的一個線程裡
/// 執行一些操作。耗時的操作(比如下載下傳和資料庫事務)在長時間運作時可能會導緻使用者界面
/// 始終處于“未響應”狀态。
///
/// 該控件有三個事件:DoWork、ProgressChanged、RunWorkerCompleted。
/// 在程式中調用 RunWorkerAsync() 方法則會啟動 DoWork 事件;當在事件處理過程中,調用
/// ReportProgress() 方法則會啟動 ProgressChanged 事件;而當 DoWork 事件處理完成時
/// 則會觸發 RunWorkerCompleted 事件。
///
/// 注意:如果在 DoWork 事件中操作任何使用者界面對象,界面仍然會出現“未響應”;應該在事件
/// ProgressChanged 和 RunWorkerCompleted 中和窗體進行通信。
/// </summary>
// 在程式中調用 RunWorkerAsync() 将會觸發該事件:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// sender:表示觸發該事件的控件對象
// e 有三個屬性:Cancel、Argument、Result
// 1、Cancel:DoWork 事件中的代碼應定期檢查 CancellationPending 屬性值,并在該值
// 為 true 時終止操作,true表示應用程式已經請求取消背景操作,此時 Cancel 應設定
// 為 true,同時 RunWorkerCompleted 事件處理程式中的Cancelled也變為 true。
if (backgroundWorker1.CancellationPending == true)
{
e.Cancel = true;
return;
}
// 2、Argument:觸發 DoWork 事件的方法 RunWorkerAsync() 有兩種重載,一種無參,
// 另一種有一個object類型的參數;當調用有參方法時,e 的 Argument 屬性将會指向
// 這個參數。
string str = e.Argument.ToString(); // 擷取 RunWorkerAsync() 傳遞過來的值
for (int i = 1; i <= 100; i++)
{
string strr = "第" + i + "句:" + str;
// 觸發 ProgressChanged 事件
backgroundWorker1.ReportProgress(i, strr);
if (i == 50)
{
// 此方法隻是請求取消,此處并沒有取消。
backgroundWorker1.CancelAsync();
MessageBox.Show("請求取消背景操作!");
if (backgroundWorker1.CancellationPending == true)
{
e.Cancel = true;
MessageBox.Show("背景程式中斷!");
return;
}
}
Thread.Sleep(200);
}
// 3、Result:此處将Result設定成什麼,RunWorkerCompleted 事件中的Result就是什麼。
e.Result = "完美結束!";
}
// 在 DoWork 事件中調用 ReportProgress() 方法就會觸發該事件。
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// ReportProgress() 有兩種重載:
// void ReportProgress(int persentProgress);
// void ReportProgress(int persentProgress, object userState);
// ReportProgress() 的第一個參數一般用來報告該背景操作完成的進度,可以通過
// ProgressChanged 事件中 e 的 ProgressPersentage 屬性來擷取。如果還想傳遞
// 更多的參數,可以使用參數 userState,可以通過事件 e 的 UserState屬性來擷取。
progressBar1.Value = e.ProgressPercentage;
label1.Text = e.UserState.ToString();
}
// 當 DoWork 事件處理程式結束之後将會觸發此事件。
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show("背景程式出錯:" + e.Error.Message.ToString());
}
else if (e.Cancelled)
{
MessageBox.Show("背景程式被終止!");
}
else
{
MessageBox.Show("背景程式運作結束!\r\n" + e.Result);
}
}
// 啟動背景程式
private void button1_Click(object sender, EventArgs e)
{
if (backgroundWorker1.IsBusy)
{
MessageBox.Show("背景程式正在執行!");
}
else
{
// 啟動背景程式
backgroundWorker1.RunWorkerAsync("Hello World");
}
backgroundWorker1.WorkerReportsProgress = true; // 設定支援報告進度更新
backgroundWorker1.WorkerSupportsCancellation = true; // 設定支援取消背景操作
}
}
}