適用場景:大量短暫工作、等待 I/O、不需精確控制執行緒生命週期。CLR 內建執行緒池,自動調整執行緒數量(最小/最大閾值)。
// 佇列工作項
ThreadPool.QueueUserWorkItem(WaitCallback callback);
ThreadPool.QueueUserWorkItem(WaitCallback callback, object state);
// 設定執行緒池大小(.NET Core/5+ 建議勿手動調整)
ThreadPool.SetMinThreads(worker, io);
ThreadPool.SetMaxThreads(worker, io);
ThreadPool.GetAvailableThreads(out worker, out io);
using System;
using System.Collections;
using System.Threading;
public class SomeState
{
public int Cookie;
public SomeState(int cookie) { Cookie = cookie; }
}
public class Alpha
{
public Hashtable HashCount = new Hashtable();
public ManualResetEvent EventX;
public static int Count, MaxCount;
public Alpha(int max) { MaxCount = max; }
public void Beta(object state)
{
var s = (SomeState)state;
Console.WriteLine($" {Thread.CurrentThread.GetHashCode()} {s.Cookie} :");
Console.WriteLine($"HashCount.Count=={HashCount.Count}, Thread.HashCode=={Thread.CurrentThread.GetHashCode()}");
lock (HashCount)
{
int key = Thread.CurrentThread.GetHashCode();
if (!HashCount.ContainsKey(key)) HashCount[key] = 0;
HashCount[key] = (int)HashCount[key] + 1;
}
Thread.Sleep(2000);
if (Interlocked.Increment(ref Count) == MaxCount)
{
Console.WriteLine("\nSetting eventX");
EventX.Set();
}
}
}
public class SimplePool
{
public static int Main()
{
Console.WriteLine("Thread Pool Sample:");
const int MaxCount = 10;
var eventX = new ManualResetEvent(false);
Console.WriteLine($"Queuing {MaxCount} items to Thread Pool");
var alpha = new Alpha(MaxCount) { EventX = eventX };
ThreadPool.QueueUserWorkItem(new WaitCallback(alpha.Beta), new SomeState(0));
for (int i = 1; i < MaxCount; i++)
{
Console.WriteLine($"Queue to Thread Pool {i}");
ThreadPool.QueueUserWorkItem(new WaitCallback(alpha.Beta), new SomeState(i));
}
Console.WriteLine("Waiting for Thread Pool to drain");
eventX.WaitOne(Timeout.Infinite, true);
Console.WriteLine("Thread Pool has been drained (Event fired)\nLoad across threads");
foreach (object k in alpha.HashCount.Keys)
Console.WriteLine($"{k} {alpha.HashCount[k]}");
Console.ReadLine();
return 0;
}
}

| 類別 | 用途 |
|---|---|
SomeState | 封裝傳遞給工作項的資料 |
ManualResetEvent | 訊號旗標:Set() 釋放所有等待者,WaitOne() 阻塞直到訊號 |
Interlocked.Increment | 原子遞增,無需 lock |
WaitCallback | 委托簽名 void Callback(object state) |
適用場景:週期性檢查、定時清理、排程任務。建立時指定 TimerCallback 委托、狀態物件、延遲、間隔。
using System;
using System.Threading;
class TimerExampleState
{
public int Counter;
public Timer Timer;
}
class App
{
public static void Main()
{
var s = new TimerExampleState();
TimerCallback callback = CheckStatus;
Timer timer = new Timer(callback, s, 1000, 1000); // 1秒後開始,每1秒執行
s.Timer = timer;
while (s.Timer != null) Thread.Sleep(0); // 主執行緒等待
Console.WriteLine("Timer example done.");
Console.ReadLine();
}
static void CheckStatus(object state)
{
var s = (TimerExampleState)state;
s.Counter++;
Console.WriteLine($"{DateTime.Now.TimeOfDay} Checking Status {s.Counter}.");
if (s.Counter == 5)
{
s.Timer.Change(10000, 2000); // 10秒後重啟,間隔改2秒
Console.WriteLine("changed...");
}
if (s.Counter == 10)
{
Console.WriteLine("disposing of timer...");
s.Timer.Dispose();
s.Timer = null; // 主執行緒循環結束條件
}
}
}
| 方法 | 說明 |
|---|---|
Change(dueTime, period) | 動態修改延遲與間隔(-1 表示停用) |
Dispose() | 釋放定時器資源,停止觸發 |
| 特性 | ThreadPool | Timer | Task / Task.Run |
|---|---|---|---|
| 適用 | 火後不顧工作項 | 週期性/定時觸發 | 現代非同步、可組合、支援 await |
| 回傳值 | 無 | 無 | Task<T> |
| 異常處理 | 難捕捉 | 難捕捉 | 自然傳播 |
| 取消 | 不支援 | Dispose | CancellationToken |
| 排程精度 | 無 | 毫秒級 | 配合 Timer/Task.Delay |
Task.Run、async/awaitTask.Run + 自訂 TaskScheduler 或專用執行緒System.Threading.Timer 或 Microsoft.Extensions.Hosting.BackgroundServiceThreadPool 自動化管理大量短暫工作項,Timer 提供定時/週期觸發能力。兩者結合 ManualResetEvent、Interlocked 可構建完整的背景處理管線。現代 .NET 開發應以 Task、async/await、Channels、BackgroundService 為主,僅在相容舊代碼或極端效能場景直接使用 ThreadPool/Timer。