WinForms 專案中大量使用執行緒與非同步呼叫,手動管理 Thread、Control.Invoke、Thread.Sleep 容易產生死結、競爭條件與 UI 凍結。.NET 2.0 引入 BackgroundWorker 元件,大幅簡化安全多執行緒開發。
ProgressChanged、RunWorkerCompleted 事件)WorkerSupportsCancellation)WorkerReportsProgress)using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
namespace UseBackgroundWorker {
public partial class Form1 : Form {
private XmlDocument document = null;
public Form1() { InitializeComponent(); }
private void downloadButton_Click(object sender, EventArgs e) {
this.backgroundWorker1.RunWorkerAsync();
this.downloadButton.Enabled = false;
// 簡易等待示範(實務建議用非同步模式)
while (this.backgroundWorker1.IsBusy) Application.DoEvents();
this.downloadButton.Enabled = true;
}
// 背景執行緒:執行耗時工作
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {
document = new XmlDocument();
document.Load(@"https://www.tailspintoys.com/sample.xml");
Thread.Sleep(5000); // 模擬長時間操作
}
// UI 執行緒:完成後自動在此執行
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
if (e.Error == null) {
MessageBox.Show(document.InnerXml, "Download Complete");
} else {
MessageBox.Show("Failed to download file", "Download failed",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
| 成員 | 執行緒 | 用途 |
|---|---|---|
DoWork | 背景執行緒 | 執行耗時邏輯,不可直接操作 UI |
ProgressChanged | UI 執行緒 | 回報進度(需 WorkerReportsProgress=true,呼叫 ReportProgress) |
RunWorkerCompleted | UI 執行緒 | 完成處理,可安全存取 UI、檢查 e.Error、e.Cancelled、e.Result |
CancellationPending | 背景執行緒 | 在 DoWork 中輪詢,若為 true 則設定 e.Cancel = true 並返回 |
while (IsBusy) DoEvents():阻塞 UI 執行緒,失去非同步優勢。應改用事件驅動模式。CancellationPending。ReportProgress(percentage, userState) 傳遞複雜資料。DoWork 發生的例外會自動包裝在 RunWorkerCompletedEventArgs.Error 中,不會使應用程式崩潰。BackgroundWorker 是微軟推薦的 WinForms 多執行緒解決方案,讓執行緒安全程式設計變得直觀簡單。