C#線(xiàn)程池ThreadPool用法簡(jiǎn)介
一、ThreadPool概述
提供一個(gè)線(xiàn)程池,該線(xiàn)程池可用于執(zhí)行任務(wù)、發(fā)送工作項(xiàng)、處理異步 I/O、代表其他線(xiàn)程等待以及處理計(jì)時(shí)器。
創(chuàng)建線(xiàn)程需要時(shí)間。如果有不同的小任務(wù)要完成,就可以事先創(chuàng)建許多線(xiàn)程/在應(yīng)完成這些任務(wù)時(shí)發(fā)出請(qǐng)求。不需要自己創(chuàng)建這樣一個(gè)列表。該列表由ThreadPool類(lèi)托管。
這個(gè)類(lèi)會(huì)在需要時(shí)增減池中線(xiàn)程的線(xiàn)程數(shù),直到最大的線(xiàn)程數(shù)。
如果有更多的作業(yè)要處理,線(xiàn)程池中線(xiàn)程的個(gè)數(shù)也達(dá)到了極限,最新的作業(yè)就要排隊(duì),且必須等待線(xiàn)程完成其任務(wù)。
線(xiàn)程池使用起來(lái)很簡(jiǎn)單,但它有一些限制
- 線(xiàn)程池中的所有線(xiàn)程都是后臺(tái)線(xiàn)程。如果進(jìn)程的所有前臺(tái)線(xiàn)程都結(jié)束了,所有的后臺(tái)線(xiàn)程 就會(huì)停止。不能把入池的線(xiàn)程改為前臺(tái)線(xiàn)程。
- 不能給入池的線(xiàn)程設(shè)置優(yōu)先級(jí)或名稱(chēng)。
- 對(duì)于COM對(duì)象,入池的所有線(xiàn)程都是多線(xiàn)程單元(multithreaded apartment, MTA)線(xiàn)程。許 多COM對(duì)象都需要單線(xiàn)程單元(single-threaded apartment, MTA)線(xiàn)程。
- 入池的線(xiàn)程只能用于時(shí)間較短的任務(wù)。如果線(xiàn)程要一直運(yùn)行(如Word的拼寫(xiě)檢杳器線(xiàn)程), 就應(yīng)使用Thread類(lèi)創(chuàng)建一個(gè)線(xiàn)程.
使用線(xiàn)程池線(xiàn)程的操作的情況包括
- 當(dāng)您創(chuàng)建Task或Task對(duì)象以異步方式執(zhí)行某項(xiàng)任務(wù),默認(rèn)情況下任務(wù)調(diào)度在線(xiàn)程池線(xiàn)程上運(yùn)行的。
- 異步計(jì)時(shí)器使用線(xiàn)程池。 線(xiàn)程池線(xiàn)程從System.Threading.Timer類(lèi)執(zhí)行回調(diào),和從System.Timers.Timer類(lèi)引發(fā)事件。
- 當(dāng)使用已注冊(cè)的等待句柄時(shí),系統(tǒng)線(xiàn)程監(jiān)視等待句柄的狀態(tài)。 等待操作完成后,從線(xiàn)程池的工作線(xiàn)程將執(zhí)行相應(yīng)的回調(diào)函數(shù)。
- 當(dāng)您調(diào)用QueueUserWorkItem方法進(jìn)行排隊(duì),以在線(xiàn)程池線(xiàn)程上執(zhí)行的方法。 為此,可將該方法傳遞WaitCallback委托。
二、方法
- GetAvailableThreads(Int32, Int32):檢索由 GetMaxThreads(Int32, Int32) 方法返回的最大線(xiàn)程池線(xiàn)程數(shù)和當(dāng)前活動(dòng)線(xiàn)程數(shù)之間的差值。
- GetMaxThreads(Int32, Int32) :檢索可以同時(shí)處于活動(dòng)狀態(tài)的線(xiàn)程池請(qǐng)求的數(shù)目。 所有大于此數(shù)目的請(qǐng)求將保持排隊(duì)狀態(tài),直到線(xiàn)程池線(xiàn)程變?yōu)榭捎谩?/li>
- SetMaxThreads(Int32, Int32) :設(shè)置可以同時(shí)處于活動(dòng)狀態(tài)的線(xiàn)程池的請(qǐng)求數(shù)目。 所有大于此數(shù)目的請(qǐng)求將保持排隊(duì)狀態(tài),直到線(xiàn)程池線(xiàn)程變?yōu)榭捎谩?/li>
- GetMinThreads(Int32, Int32):發(fā)出新的請(qǐng)求時(shí),在切換到管理線(xiàn)程創(chuàng)建和銷(xiāo)毀的算法之前檢索線(xiàn)程池按需創(chuàng)建的線(xiàn)程的最小數(shù)量。
- SetMinThreads(Int32, Int32):發(fā)出新的請(qǐng)求時(shí),在切換到管理線(xiàn)程創(chuàng)建和銷(xiāo)毀的算法之前設(shè)置線(xiàn)程池按需創(chuàng)建的線(xiàn)程的最小數(shù)量。
- QueueUserWorkItem(WaitCallback, Object):將方法排入隊(duì)列以便執(zhí)行,并指定包含該方法所用數(shù)據(jù)的對(duì)象。 此方法在有線(xiàn)程池線(xiàn)程變得可用時(shí)執(zhí)行。
- RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, Object, Int32, Boolean) :注冊(cè)一個(gè)等待 WaitHandle 的委托,并指定一個(gè) 32 位有符號(hào)整數(shù)來(lái)表示超時(shí)值(以毫秒為單位)。
三、設(shè)置和獲取線(xiàn)程數(shù)方法
池中的最大線(xiàn)程數(shù)是可配置的。在雙核CPU中,默認(rèn)設(shè)置為1023 個(gè)工作線(xiàn)程和1000個(gè)I/O線(xiàn)程。也可以指定在創(chuàng)建線(xiàn)程池時(shí)應(yīng)立即啟動(dòng)的最小線(xiàn)程數(shù),以及線(xiàn)程池 中可用的最大線(xiàn)程數(shù)。
int i = 0; int j = 0; //前面是輔助(也就是所謂的工作者)線(xiàn)程,后面是I/O線(xiàn)程 ThreadPool.GetMaxThreads(out i, out j); Console.WriteLine(i.ToString() + " " + j.ToString()); //默認(rèn)都是1000 //獲取空閑線(xiàn)程,由于現(xiàn)在沒(méi)有使用異步線(xiàn)程,所以為空 ThreadPool.GetAvailableThreads(out i, out j); Console.WriteLine(i.ToString() + " " + j.ToString()); //默認(rèn)都是1000
四、將方法排入隊(duì)列以便執(zhí)行:QueueUserWorkItem(WaitCallback, Object)
將方法排入隊(duì)列以便執(zhí)行,并指定包含該方法所用數(shù)據(jù)的對(duì)象。 此方法在有線(xiàn)程池線(xiàn)程變得可用時(shí)執(zhí)行。
public static bool QueueUserWorkItem (System.Threading.WaitCallback callBack, object state);
實(shí)例:
static void Main(string[] args) { Person p = new Person(1, "劉備"); //啟動(dòng)工作者線(xiàn)程 ThreadPool.QueueUserWorkItem(new WaitCallback(RunWorkerThread), p); } static void RunWorkerThread(object obj) { Thread.Sleep(200); Console.WriteLine("線(xiàn)程池線(xiàn)程開(kāi)始!"); Person p = obj as Person; Console.WriteLine(p.Name); } public class Person { public Person(int id, string name) { Id = id; Name = name; } public int Id { get; set; } public string Name { get; set; } }
五、RegisterWaitForSingleObject 注冊(cè)等待句柄
注冊(cè)一個(gè)等待 WaitHandle 的委托,并指定一個(gè)數(shù)來(lái)表示超時(shí)值(以毫秒為單位)。
將指定的方法排隊(duì)到線(xiàn)程池,當(dāng)超時(shí)或者等待委托接收到信號(hào)時(shí),輔助線(xiàn)程將執(zhí)行此方法,即主線(xiàn)程控制輔助線(xiàn)程什么時(shí)候開(kāi)始執(zhí)行。
public static System.Threading.RegisteredWaitHandle RegisterWaitForSingleObject (System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object state, int millisecondsTimeOutInterval, bool executeOnlyOnce);
1、參數(shù)
- waitObject:要注冊(cè)的 WaitHandle。 使用 WaitHandle 而非 Mutex。
- callBack :向 waitObject 參數(shù)發(fā)出信號(hào)時(shí)調(diào)用的 WaitOrTimerCallback 委托。
- state:傳遞給委托的對(duì)象。
- millisecondsTimeOutInterval:以毫秒為單位的超時(shí)。
如果為0(零),函數(shù)將測(cè)試對(duì)象的狀態(tài)并立即返回。 如果為 -1,則函數(shù)的超時(shí)間隔永遠(yuǎn)不過(guò)期。表示間隔幾秒執(zhí)行回調(diào)方法,指當(dāng)剛加入線(xiàn)程后,它是需要過(guò)了幾秒后才會(huì)第一次執(zhí)行回調(diào)方法。如果使用了wait.Set()方法使用立即執(zhí)行回調(diào)函數(shù)而不需要等待。 - executeOnlyOnce:如果為 true,表示在調(diào)用了委托后,線(xiàn)程將不再在 waitObject 參數(shù)上等待;如果為 false,表示每次完成等待操作后都重置計(jì)時(shí)器,直到注銷(xiāo)等待。
2、返回
- RegisteredWaitHandle:封裝本機(jī)句柄的 RegisteredWaitHandle。
// TaskInfo contains data that will be passed to the callback method. public class TaskInfo { public RegisteredWaitHandle Handle = null; public string OtherInfo = "default"; } public static void Main(string[] args) { // 主線(xiàn)程使用AutoResetEvent來(lái)給已注冊(cè)的等待句柄發(fā)信號(hào), 此等待句柄執(zhí)行回調(diào)方法 AutoResetEvent ev = new AutoResetEvent(false); TaskInfo ti = new TaskInfo(); ti.OtherInfo = "First task"; // 該任務(wù)的TaskInfo包括RegisterWaitForSingleObject返回的已注冊(cè)的等待句柄。這允許在對(duì)象被發(fā)出一次信號(hào)時(shí)終止等待(參見(jiàn)WaitProc)。 ti.Handle = ThreadPool.RegisterWaitForSingleObject( ev, new WaitOrTimerCallback(WaitProc), ti, 1000, false ); // 主線(xiàn)程等待三秒,為了演示隊(duì)列中的線(xiàn)程超時(shí),然后發(fā)信號(hào). Thread.Sleep(3100); Console.WriteLine("Main thread signals."); ev.Set();//發(fā)信號(hào) // 主線(xiàn)程休眠,這應(yīng)該給回調(diào)方法執(zhí)行的時(shí)間。如果注釋掉這一行,程序通常會(huì)在ThreadPool線(xiàn)程執(zhí)行之前結(jié)束。 Thread.Sleep(1000); / /如果您自己?jiǎn)?dòng)一個(gè)線(xiàn)程,您可以通過(guò)調(diào)用thread . join來(lái)等待它結(jié)束。此選項(xiàng)在線(xiàn)程池線(xiàn)程中不可用。 } //當(dāng)注冊(cè)的等待時(shí)間超時(shí),或者WaitHandle(在本例中是AutoResetEvent)發(fā)出信號(hào)時(shí),回調(diào)方法執(zhí)行。WaitProc在事件第一次發(fā)出信號(hào)時(shí)注銷(xiāo)WaitHandle。. public static void WaitProc(object state, bool timedOut) { TaskInfo ti = (TaskInfo)state; string cause = "TIMED OUT"; if (!timedOut) //如果Timeout為false,表示接收到的信號(hào)后執(zhí)行的 { cause = "SIGNALED"; //如果回調(diào)方法執(zhí)行的話(huà)是因?yàn)閃aitHandle觸發(fā)信號(hào)的話(huà),則用反注冊(cè)等待句柄來(lái)取消回調(diào)方法將來(lái)的執(zhí)行。 if (ti.Handle != null) ti.Handle.Unregister(null);// } Console.WriteLine("WaitProc( {0} ) executes on thread {1}; cause = {2}.", ti.OtherInfo, Thread.CurrentThread.GetHashCode().ToString(), cause);//超時(shí)后執(zhí)行的 }
結(jié)果如下:
WaitProc( First task ) executes on thread 7; cause = TIMED OUT.
WaitProc( First task ) executes on thread 7; cause = TIMED OUT.
WaitProc( First task ) executes on thread 7; cause = TIMED OUT.
Main thread signals.
WaitProc( First task ) executes on thread 7; cause = SIGNALED.
到此這篇關(guān)于C#線(xiàn)程池ThreadPool的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Unity編輯器資源導(dǎo)入處理函數(shù)OnPostprocessAudio使用案例
這篇文章主要為大家介紹了Unity編輯器資源導(dǎo)入處理函數(shù)OnPostprocessAudio使用案例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08C#后臺(tái)調(diào)用前臺(tái)JS函數(shù)方法
今天小編就為大家分享一篇關(guān)于C#后臺(tái)調(diào)用前臺(tái)JS函數(shù)方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01C#數(shù)據(jù)結(jié)構(gòu)與算法揭秘一
本文一介紹了數(shù)據(jù)結(jié)構(gòu)的基本概念 而介紹了算法的基本概念,并且重點(diǎn)討論了算法時(shí)間復(fù)雜度,并且用程序予以證明2012-11-11關(guān)于c#二叉樹(shù)的實(shí)現(xiàn)
本篇文章小編為大家介紹,關(guān)于c#二叉樹(shù)的實(shí)現(xiàn)。需要的朋友參考下2013-04-04