在 WinForms 應用程式中,為了保持 UI 回應流暢,耗時運算(如檔案讀寫、網路請求、複雜計算)必須移至背景執行緒。本文將系統介紹從傳統 Thread 類別到現代 Task 非同步模式的多種實作方式,並著重說明執行緒生命週期管理與資源回收技巧。
最直接的方式是建立 System.Threading.Thread 實例,指定無參數的方法名稱(注意不是呼叫方法):
Thread thread = new Thread(new ThreadStart(DoWork));
thread.Start();
若方法需傳參數,可使用 ParameterizedThreadStart:
Thread thread = new Thread(new ParameterizedThreadStart(DoWorkWithParam));
thread.Start("參數值");
頻繁建立/銷毀線程開銷大,.NET 提供 ThreadPool 重用線程:
ThreadPool.QueueUserWorkItem(state => DoWork());
WinForms 專用的 BackgroundWorker 內建進度報告與完成事件,適合需更新 UI 的場景:
var bw = new BackgroundWorker();
bw.DoWork += (s, e) => { /* 背景工作 */ };
bw.ProgressChanged += (s, e) => { /* 更新進度條 */ };
bw.RunWorkerCompleted += (s, e) => { /* 完成處理 */ };
bw.WorkerReportsProgress = true;
bw.RunWorkerAsync();
.NET 4.5 後推薦使用 Task 配合 async/await,程式碼更簡潔、例外處理更直觀:
private async void btnStart_Click(object sender, EventArgs e)
{
btnStart.Enabled = false;
try
{
await Task.Run(() => DoHeavyWork());
MessageBox.Show("完成");
}
catch (Exception ex)
{
MessageBox.Show("錯誤:" + ex.Message);
}
finally
{
btnStart.Enabled = true;
}
}
優點:自動捕捉同步上下文,續執行自動回到 UI 執行緒,無需手動 Invoke。
Thread.IsBackground = false,會阻塞進程結束,需確保正常返回。IsBackground = true,主視窗關閉時自動終止,適合非關鍵任務。CancellationToken 協作式取消,避免強制 Abort() 導致資料損壞。var cts = new CancellationTokenSource();
var token = cts.Token;
Task.Run(() => {
for (int i = 0; i < 100; i++)
{
token.ThrowIfCancellationRequested();
DoStep(i);
}
}, token);
// 需要取消時
cts.Cancel();
Control.Invoke 或 BeginInvoke,或在 async/await 後直接操作。Task 或 DoWork 內部 try-catch。SemaphoreSlim 或 Task.WhenAll 批次控制,防止資源耗盡。針對 WinForms 多線程開發,建議優先採用 Task.Run + async/await,搭配 CancellationToken 實現優雅取消;簡單場景可用 BackgroundWorker;僅在需精細控制線程屬性(如優先權、單執行緒單元)時直接使用 Thread。記住:線程池線程屬於進程共享,切勿長時間佔用;自建線程用畢須確保正常結束或標記為背景線程,才能實現「跑完即回收、不佔用系統資源」的目標。