地址:https://www.cnblogs.com/scmail81/archive/2018/08/19/9503266.htmlhtml
CLR線程池並不會在CLR初始化時當即創建線程,而是在應用程序要建立線程來運行任務時,線程池才初始化一個線程。
線程池初始化時是沒有線程的,線程池裏的線程的初始化與其餘線程同樣,可是在完成任務之後,該線程不會自行銷燬,而是以掛起的狀態返回到線程池。直到應用程序再次向線程池發出請求時,線程池裏掛起的線程就會再度激活執行任務。
這樣既節省了創建線程所形成的性能損耗,也可讓多個任務反覆重用同一線程,從而在應用程序生存期內節約大量開銷。網絡
經過CLR線程池所創建的線程老是默認爲後臺線程,優先級數爲ThreadPriority.Normal。ide
CLR線程池分爲工做者線程(workerThreads)與I/O線程(completionPortThreads)兩種:函數
線程池的最大值通常默認爲1000、2000。當大於此數目的請求時,將保持排隊狀態,直到線程池裏有線程可用。性能
使用CLR線程池的工做者線程通常有兩種方式:測試
要注意,不管是經過ThreadPool.QueueUserWorkItem()仍是委託,調用的都是線程池裏的線程。優化
經過如下兩個方法能夠讀取和設置CLR線程池中工做者線程與I/O線程的最大線程數。spa
若想測試線程池中有多少線程正在投入使用,能夠經過ThreadPool.GetAvailableThreads(out in workThreads,out int conoletionPortThreads)方法。操作系統
方法 | 說明 |
GetAvailableThreads | 剩餘空閒線程數 |
GetMaxThreads | 最多可用線程數,全部大於此數目的請求將保持排隊狀態,直到線程池線程變爲可用 |
GetMinThreads | 檢索線程池在新請求預測中維護的空閒線程數 |
QueueUserWorkItem | 啓動線程池裏得一個線程(隊列的方式,如線程池暫時沒空閒線程,則進入隊列排隊) |
SetMaxThreads | 設置線程池中的最大線程數 |
SetMinThreads | 設置線程池最少須要保留的線程數 |
咱們可使用線程池來解決上面的大部分問題,跟使用單個線程相比,使用線程池有以下優勢:線程
一、縮短應用程序的響應時間。由於在線程池中有線程的線程處於等待分配任務狀態(只要沒有超過線程池的最大上限),無需建立線程。
二、沒必要管理和維護生存週期短暫的線程,不用在建立時爲其分配資源,在其執行完任務以後釋放資源。
三、線程池會根據當前系統特色對池內的線程進行優化處理。
總之使用線程池的做用就是減小建立和銷燬線程的系統開銷。在.NET中有一個線程的類ThreadPool,它提供了線程池的管理。
ThreadPool是一個靜態類,它沒有構造函數,對外提供的函數也所有是靜態的。其中有一個QueueUserWorkItem方法,它有兩種重載形式,以下:
public static bool QueueUserWorkItem(WaitCallback callBack):將方法排入隊列以便執行。此方法在有線程池線程變得可用時執行。
public static bool QueueUserWorkItem(WaitCallback callBack,Object state):將方法排入隊列以便執行,並指定包含該方法所用數據的對象。此方法在有線程池線程變得可用時執行。
QueueUserWorkItem方法中使用的的WaitCallback參數表示一個delegate,它的聲明以下:
public delegate void WaitCallback(Object state)
若是須要傳遞任務信息能夠利用WaitCallback中的state參數,相似於ParameterizedThreadStart委託。
下面是一個ThreadPool的例子,代碼以下:
using System; using System.Collections; using System.ComponentModel; using System.Diagnostics; using System.Threading; namespace ConsoleApp1 { class ThreadPoolDemo { public ThreadPoolDemo() { } public void Work() { ThreadPool.QueueUserWorkItem(new WaitCallback(CountProcess)); ThreadPool.QueueUserWorkItem(new WaitCallback(GetEnvironmentVariables)); } /// <summary> /// 統計當前正在運行的系統進程信息 /// </summary> /// <param name="state"></param> private void CountProcess(object state) { Process[] processes = Process.GetProcesses(); foreach (Process p in processes) { try { Console.WriteLine("進程信息:Id:{0},ProcessName:{1},StartTime:{2}", p.Id, p.ProcessName, p.StartTime); } catch (Win32Exception e) { Console.WriteLine("ProcessName:{0}", p.ProcessName); } finally { } } Console.WriteLine("獲取進程信息完畢。"); } /// <summary> /// 獲取當前機器系統變量設置 /// </summary> /// <param name="state"></param> public void GetEnvironmentVariables(object state) { IDictionary list = System.Environment.GetEnvironmentVariables(); foreach (DictionaryEntry item in list) { Console.WriteLine("系統變量信息:key={0},value={1}", item.Key, item.Value); } Console.WriteLine("獲取系統變量信息完畢。"); } } }
using System; using System.Threading; namespace ConsoleApp1 { class Program { static void Main(string[] args) { ThreadPoolDemo tpd1 = new ThreadPoolDemo(); tpd1.Work(); Thread.Sleep(5000); Console.WriteLine("OK"); Console.ReadLine(); } } }