[C#.NET][Thread] 執行緒集區 - ThreadPool
看了安德魯的文章,可以讓人裡解ThreadPool背後在玩的把戲 ThreadPool 實作 #1. 基本概念,絕對會讓您收獲不少。
執行緒集區會維持一個最小閒置執行緒數目,當使用ThreadPool.QueueUserWorkItem方法時會喚醒正在休眠的執行緒,這樣一來就比我們不斷直接使用Thread類別重新建立執行緒還要來的節省資源一點,執行緒集區內的執行緒工作滿檔時,會再自動增加執行緒的數量。
另外MSDN有提到,
如果應用程式受到突然增加的活動影響 (例如,大量佇列的執行緒集區工作),請使用 SetMinThreads 方法增加最小閒置執行緒的數目。否則,建立新閒置執行緒時的內建延遲可能會造成瓶頸。
這表示若有需要大量執行緒數量要增加時,反而會因為這些延遲而拖垮系統,保哥也是曾經受到它的荼毒 ,使用 ThreadPool 時應注意預設同時執行的 Thread 數量 。
ThreadPool.QueueUserWorkItem方法需要傳入一個WaitCallback委派,這個委派的簽名是
public delegate void WaitCallback (
Object state
)
所以只要建立跟它有相同簽名的方法,就可以建立WaitCallback委派了。
ThreadPool.QueueUserWorkItem方法只有兩種多載,除了固定要傳WaitCallback委派,另一個參數就是object物件,所以表示我們可以傳很大的東西進去DoWorker(object number)方法裡
static void Main(string[] args) { ThreadPool.QueueUserWorkItem(new WaitCallback(DoWorker), i); ThreadPool.QueueUserWorkItem(new WaitCallback(DoWorker)); } static void DoWorker(object number) { //TODO.. }
先來看看簡單的使用範例
傳入一個參數
static void Main(string[] args) { for (int i = 0; i < 10; i++) { ThreadPool.QueueUserWorkItem(new WaitCallback(DoWorker), i); } Console.WriteLine("Main thread exit"); Console.ReadKey(); } static void DoWorker(object number) { Thread t = Thread.CurrentThread; Console.WriteLine("No.{0}-Thread[{1}]:{2}", number, t.ManagedThreadId, t.ThreadState); Thread.Sleep(1000); }
因為閒置的執行緒被喚醒,所以可以看到,有許多重複的執行緒會出現
傳入多個參數
若需要傳入不只一個參數,我們可以利用類別(class)或結構(struct)來傳入,當然你也可以傳入集合…反正你想的到的資料型態什麼都能傳,只要再DoWorker方法裡記得轉型就可以了。
static void Main(string[] args) { Book book = new Book(); book.author = "余小章"; book.price = 1000; book.title = "MVP"; ThreadPool.QueueUserWorkItem(new WaitCallback(DoWorker), book); Console.WriteLine("Main thread exit"); Console.ReadKey(); } static void DoWorker(object book) { Thread t = Thread.CurrentThread; Book b = (Book)book; Console.WriteLine("Thread[{0}]:{1}", t.ManagedThreadId, t.ThreadState); Console.WriteLine("author:{0},title{1},price:{2}", b.author, b.title, b.price); Thread.Sleep(1000); } public struct Book { public decimal price; public string title; public string author; }
浙公网安备 33010602011771号