.NET Thread.Start() 僅接受無參數的 ThreadStart 委派,若需向執行緒方法傳遞參數,需採用間接方式。本文介紹三種常用模式,並說明適用場景。
public class Worker
{
private readonly string _param;
public Worker(string param) => _param = param;
public void DoWork() => Console.WriteLine(_param);
}
// 使用
var w = new Worker("ParameterValue");
new Thread(w.DoWork).Start();
public class Worker
{
public void DoWork(object state) => Console.WriteLine((string)state);
}
// 使用
ThreadPool.QueueUserWorkItem(new WaitCallback(new Worker().DoWork), "ParameterValue");
state 參數型別為 object 可傳遞任意資料。delegate string WorkDelegate(string param);
public class Worker
{
public string DoWork(string p) => $"結果:{p}";
}
// 使用
var worker = new Worker();
WorkDelegate d = worker.DoWork;
d.BeginInvoke("paramValue", ar => {
var result = d.EndInvoke(ar);
Console.WriteLine(result);
}, null);
EndInvoke、可透過 IAsyncResult 狀態輪詢/等待。Task/async-await。封裝為物件或 Tuple:
// 匿名型別
ThreadPool.QueueUserWorkItem(_ => {
var p = (dynamic)_;
Console.WriteLine($"{p.P1} + {p.P2}");
}, new { P1 = "A", P2 = "B" });
// 非同步委派多參數
delegate string MultiDelegate(string p1, string p2);
// .NET 4.0+ 推薦寫法
Task.Run(() => DoWork("param")); // 無回傳值
var result = await Task.Run(() => Compute("param")); // 有回傳值、異常處理自然
Task 統一了工作排程、回傳值、取消、例外處理,是現代 .NET 非同步程式設計的標準抽象。
| 場景 | 建議方案 |
|---|---|
| 簡單背景工作、參數固定 | 建構函式 + Thread |
| 大量短時工作、需效能 | ThreadPool / Task.Run |
| 需回傳值、例外處理、續作邏輯 | async-await / Task |
| Legacy 專案維護 | 非同步委派 (APM) |