BackgroundWorker元件介紹
BackgroundWorker是·net裡用來執行多線程任務的控件,它允許程式設計者在一個單獨的線程上執行一些操作。
常用方法
- RunWorkerAsync 開始執行背景操作。引發 DoWork 事件
- CancelAsync 請求取消挂起的背景操作。注意:這個方法是将 CancellationPending 屬性設定為 true,并不會終止背景操作。在背景操作中要檢查CancellationPending 屬性,來決定是否要繼續執行耗時的操作。
- ReportProgress引發 ProgressChanged 事件。
常用屬性
- CancellationPending 訓示應用程式是否已請求取消背景操作。隻讀屬性,預設為 false,當執行了 CancelAsync 方法後,值為 true。
- WorkerSupportsCancellation訓示是否支援異步取消。要執行 CancelAsync 方法,需要先設定該屬性為 true。
- WorkerReportsProgress訓示是否能報告進度。要執行 ReportProgress 方法,需要先設定該屬性為 true。
注意: - 在 DoWork 事件處理程式中不操作任何使用者界面對象。而應該通過 ProgressChanged 和RunWorkerCompleted 事件與使用者界面進行通信。
- 如果想在 DoWork 事件處理程式中和使用者界面的控件通信,可在用 ReportProgress 方法。ReportProgress(int percentProgress, object userState),可以傳遞一個對象。ProgressChanged 事件可以從參數ProgressChangedEventArgs 類的UserState 屬性得到這個資訊對象。這個事件也可以實作進度條功能,把任務的進度實時呈現給使用者。
- 簡單的程式用BackgroundWorker 比 Thread 友善,Thread中和使用者界面上的控件通信比較麻煩,需要用委托來調用控件的 Invoke 或BeginInvoke 方法,沒有 BackgroundWorker 友善。
執行個體
public partial class Analyse : Form
{
public Analyse()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false; //線程間操作無效: 從不是建立控件“XXX”的線程通路它。
}
/// <summary>
/// Analyse
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Analyse_btn_Click(object sender, EventArgs e)
{
try
{
// 資料分析
if (!bgWorker_Process.IsBusy)
{
AnalyseResults = new List<AnalyseResultMdl>();
this.bgWorker_Process = new BackgroundWorker() //new一個新的,避免重複添加相同和其他無用DoWork,也可以不用new
{
WorkerReportsProgress = true //能否報告進度更新
};
this.bgWorker_Process.DoWork += new DoWorkEventHandler(Analyse_DoWork);
this.bgWorker_Process.ProgressChanged += new ProgressChangedEventHandler(bgWorker_Process_ProgressChanged);
this.bgWorker_Process.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_Process_RunWorkerCompleted);
this.bgWorker_Process.RunWorkerAsync(); // 運作 backgroundWorker 元件
}
else
{
MessageBox.Show($"等待其他操作完成再執行...");
}
}
catch (Exception ex)
{
MessageBox.Show($"分析出錯:{ex}");
}
}
/// <summary>
/// Analyse_DoWork
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Analyse_DoWork(object sender, EventArgs e)
{
int intPercentage=1;
foreach (var item in itemList)
{
bgWorker_Process.ReportProgress(Convert.ToInt32(Math.Floor(Convert.ToDouble(intPercentage * 100 / BaseDataList.Count())))); // 觸發bgWorker_Process.ProgressChanged事件
// 耗時操作
// 。。。
intPercentage++;
}
}
/// <summary>
/// 進度變化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void bgWorker_Process_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage; //progressBar1 進度條控件
}
/// <summary>
/// 程式執行完成
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void bgWorker_Process_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
else if (e.Cancelled)
{
}
else
{
this.bgWorker_Process.Dispose();
}
}
}