1、需求背景 創建線程需要時間。如果有不同的小任務完成,就可以事先創建許多線程,在應完成這些任務時發出請求。這個線程數最好在需要更多的線程時增加,在需要釋放資源時減少。 2、線程池出場 不需要自己創建這樣一個列表。該列表由ThreadPool類托管。這個類會在需要時增減池中線程的線程數,直到最大的線 ...
1、需求背景 創建線程需要時間。如果有不同的小任務完成,就可以事先創建許多線程,在應完成這些任務時發出請求。這個線程數最好在需要更多的線程時增加,在需要釋放資源時減少。 2、線程池出場 不需要自己創建這樣一個列表。該列表由ThreadPool類托管。這個類會在需要時增減池中線程的線程數,直到最大的線程數。池中的最大線程數是可配置的。 在雙核CPU中,預設設置為1023個工作線程和1000個I/O線程。四核CPU中,預設設置為2047個工作線程和1000個I/O線程。 也可以指定在創建線程池時應立即啟動的最小線程數,以及線程池中可用的最大線程數。 如果有更多的作業要處理,線程池中線程的個數也到了極限,最新的作業就要排隊,且必須等待線程完成其任務。 3、舉個慄子 下麵的實例首先讀取工作線程和I/O線程的最大線程數,把這些信息寫入控制臺中,接著在for迴圈中,調用ThreadPool.QueueUserWorkItem()方法,傳遞一個WaitCallBack類型的委托,把JobForAThread()方法賦予線程池中的線程。線程池接收到這個請求後,就會從池中選擇一個線程,來調用該方法。 如果線程池還沒有運行,就會創建一個線程池,並啟動第一個線程。如果線程池已經在運行,且有一個空閑線程來完成該任務,就把該任務傳遞給這個線程。
class CLRThread2 { public static void ThreadMethod() { int nWorkThreads; int nCompletionPortThreads; ThreadPool.GetMaxThreads(out nWorkThreads, out nCompletionPortThreads); Console.WriteLine("Max worker threads:{0},I/O completion threads:{1}", nWorkThreads, nCompletionPortThreads); for (int i = 0; i < 5; i++) { ThreadPool.QueueUserWorkItem(JobForAThread); } Thread.Sleep(3000); } static void JobForAThread(object state) { for (int i = 0; i < 3; i++) { Console.WriteLine("loop {0},running inside pooled thread {1}", i, Thread.CurrentThread.ManagedThreadId); Thread.Sleep(50); } } }
4、線程池的使用限制 線程池用起來簡單,但它有一些限制:
- 線程池中的所有線程都是後臺線程。如果進程的所有前臺線程都結束了,所有的後臺線程就會停止。不能把入池的線程改為前臺線程。
- 不能給入池的線程設置優先順序或名稱
- 對於COM對象,入池的所有線程都是多線程單元(multitihreaded apartment,MTA)線程。許多COM對象都需要單線程單元(single-threaded apartmeng,STA)線程
- 入池的線程只能用於時間較短的任務。如果線程要一直運行(如Word的拼寫檢查器線程),就應該使用Thread類創建一個線程。