多執行緒是提升應用程式回應性與資源利用率的關鍵技術。本文從進程與執行緒的區別、多執行緒優勢、應用場合、核心類別 `Thread` 的建構與控制、計時器、前景/背景執行緒等基礎面向完整建構知識體系。
| 概念 | 進程 | 執行緒 |
|---|---|---|
| 定義 | 資源配置基本單位(PCB、程式碼段、資料段) | CPU 排程基本單位(輕量級進程) |
| 資源 | 獨立位址空間 | 共享進程位址空間,僅擁有堆疊、暫存器、執行緒 ID |
| 切換開銷 | 大(切換位址空間) | 小(共享位址空間) |
| 關係 | 至少包含一個主執行緒,可建立多個子執行緒 | 隸屬於單一進程 |
代價: 同步複雜度、死結風險、除錯困難、上下文切換開銷。
多位搬運工(執行緒)並行搬運共同貨堆(共享資源),展示 `Thread.Start`、`ParameterizedThreadStart`、共享靜態欄位競爭(未加同步,僅示範基本啟動)。
public class Mover {
public static int GoodsTotal = 200;
public static int IntervalTime = 10;
public string Name { get; set; }
public int LaborAmount { get; set; }
public void Move() {
while (GoodsTotal > 0) {
GoodsTotal -= LaborAmount;
Console.WriteLine($"{Name} 搬運 {LaborAmount} 於 {DateTime.Now.Millisecond}");
Thread.Sleep(IntervalTime);
}
}
}
// 啟動
new Thread(new ThreadStart(m1.Move)).Start();
new Thread(new ParameterizedThreadStart(m2.Move)).Start(10);
// 1. ThreadStart 無參數委派
new Thread(new ThreadStart(Method)).Start();
// 2. ParameterizedThreadStart 有參數委派
new Thread(new ParameterizedThreadStart(MethodWithParam)).Start(arg);
// 3. 匿名委派
new Thread(delegate { /* ... */ }).Start();
// 4. Lambda 運算式
new Thread(() => { /* ... */ }).Start();
// 5. 直接指定方法群組 (C# 2.0+)
new Thread(Method).Start();
`System.Threading.Timer` 於執行緒池執行回呼,適合週期性背景工作。支援變更週期、一次性觸發、取消。
TimerCallback cb = state => { /* 週期性工作 */ };
Timer timer = new Timer(cb, null, dueTime: 1000, period: 250);
// 5 秒後改為 500ms 週期
Thread.Sleep(5000);
timer.Change(0, 500);
// 5 秒後銷毀
Thread.Sleep(5000);
timer.Dispose();
原則: 監聽、非關鍵背景任務設為背景;關鍵業務、需釋放資源的任務保持前景。
// 測試差異
for (int i=0; i<10; i++) {
var t = new Thread(() => { Thread.Sleep(20000); });
t.IsBackground = true; // 註解此行觀察前景行為
t.Start();
}
Console.WriteLine("主執行緒結束");
掌握 `Thread` 基礎操作、生命週期、優先權與前背景特性,是進階多執行緒程式設計(同步、執行緒池、Task、async/await)的基石。