ThreadPool類提供一個線程池,該線程池可用於發送工作項、處理異步 I/O、代表其他線程等待以及處理計時器
線程池通過為應用程序提供一個由系統管理的輔助線程池使您可以更為有效地使用線程。一個線程監視排到線程池的若干個等待操作的狀態。當一個等待操作完成時,線程池中的一個輔助線程就會執行對應的回調函數
托管線程池中的線程為後台線程,即它們的 IsBackground 屬性為 true。這意味著在所有的前台線程都已退出後,ThreadPool 線程不會讓應用程序保持運行
也可以將與等待操作不相關的工作項排列到線程池。若要請求由線程池中的一個線程來處理工作項,請調用 QueueUserWorkItem 方法。此方法將對將被從線程池中選定的線程調用的方法或委托的引用用作參數。一個工作項排入隊列後就無法再取消它。
計時器隊列中的計時器以及已注冊的等待操作也使用線程池。它們的回調函數也會排列到線程池。
每個進程都有一個線程池。線程池的默認大小為每個可用處理器有 25 個線程。使用 SetMaxThreads 方法可以更改線程池中的線程數。每個線程使用默認的堆棧大小並按照默認的優先級運行
示例代碼:
using System; using System.Threading; public class Example { public static void Main() { string str = "param"; ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc), str); Thread.Sleep(1000); Console.ReadKey(); } static void ThreadProc(Object stateInfo) { Console.WriteLine(stateInfo); } }
QueueUserWorkItem方法將指定的方法排入隊列以便執行,並指定包含該方法所用數據的對象
1.不傳遞參數
public static bool QueueUserWorkItem(WaitCallback callBack);
2.傳遞參數
public static bool QueueUserWorkItem(WaitCallback callBack, object state);
如果將方法成功排入隊列,則為 true;否則為 false。如果排入隊列的方法僅需要單個數據項,可以將數據項強制轉換為類型 Object。如果該方法需要多個復雜數據,則必須定義包含這些數據的類。
什麼時候使用ThreadPool?
ThreadPool的作用:
另一種將任務項排列到線程池的方法,不過這個任務項是擁有等待操作的任務項
ThreadPool.RegisterWaitForSingleObject 方法 (WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean)
注冊一個等待 WaitHandle 的委托(將擁有等待操作的任務項排列到線程池中),並指定一個 32 位有符號整數來表示超時值(以毫秒為單位)。
類型:System.Threading.RegisteredWaitHandle
封裝本機句柄的 RegisteredWaitHandle。
此方法返回的 RegisteredWaitHandle 使用完畢後,請調用其 RegisteredWaitHandle.Unregister 方法來釋放對等待句柄的引用。 我們建議始終調用 RegisteredWaitHandle.Unregister 方法,即使將 executeOnlyOnce 指定為 true 也是如此。 如果調用 RegisteredWaitHandle.Unregister 方法而不是取決於注冊的等待句柄的終結器,則垃圾回收的工作效率更高。
RegisterWaitForSingleObject 方法將指定的委托排隊到線程池。 當發生以下情況之一時,輔助線程將執行委托:
指定對象處於終止狀態()。
超時間隔已過期。
RegisterWaitForSingleObject 方法檢查指定對象的 WaitHandle 的當前狀態。 如果對象狀態為非終止狀態,則此方法將注冊一個等待操作。 此等待操作由線程池中的一個線程來執行。 當對象狀態變為終止或超時間隔已過期時,委托由輔助線程執行。 如果 timeOutInterval 參數不為 0(零),並且 executeOnlyOnce 參數為 false,則每當事件收到信號或超時間隔過期時都會重置計時器。
using System; using System.Threading; using System.Runtime.CompilerServices; public class ClassForMain { private static int i = 0; public static void Main(string[] args) { //設置WaitHandle的初始狀態為非終止狀態時,則此方法將注冊一個等待操作 AutoResetEvent argv = new AutoResetEvent(false); //將超時值設置為2000毫秒,超時間隔已過期時輔助線程將執行委托 ThreadPool.RegisterWaitForSingleObject(argv, new WaitOrTimerCallback(workitem), null, 2000, false); //設置WaitHandle的狀態為終止狀態輔助線程將執行委托 argv.Set(); Console.Read(); } public static void workitem(object O, bool signaled) { i += 1; Console.WriteLine("Thread Pool Work Item Invoked:" + i.ToString()); } }
參考文章:
線程池是為突然大量爆發的線程設計的,通過有限的幾個固定線程為大量的操作服務,減少了創建和銷毀線程所需的時間,從而提高效率。
如果一個線程的時間非常長,就沒必要用線程池了(不是不能作長時間操作,而是不宜。),況且還不能控制線程池中線程的開始、掛起、和中止。
提供一個線程池,該線程池可用於執行任務、發送工作項、處理異步 I/O、代表其他線程等待以及處理計時器。