C# ThreadPool/線程池(執行序池)
C# ThreadPool/線程池(執行序池)
資料來源: https://py3939.pixnet.net/blog/post/28264441
https://dotblogs.com.tw/atowngit/2009/12/20/12557
範例01.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ThreadPoo { class ThreadPool1 { static void Main(string[] args) { System.Threading.WaitCallback waitCallback = new WaitCallback(MyThreadWork); ThreadPool.QueueUserWorkItem(waitCallback, "First"); ThreadPool.QueueUserWorkItem(waitCallback, "Second"); ThreadPool.QueueUserWorkItem(waitCallback, "Third"); Console.WriteLine("Main thread exits."); Console.ReadKey();//等待並結束 } static void MyThreadWork(object state) { Console.WriteLine("Begin of {0}", (string)state); Thread.Sleep(5000); Console.WriteLine("End of {0}", (string)state); } } }
輸出結果 :
Main thread exits.
Begin of First
Begin of Third
Begin of Second
End of First
End of Third
End of Second
範例02(匿名委派).
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ThreadPoo { class ThreadPool1 { static void Main(string[] args) { ThreadPool.QueueUserWorkItem(delegate { Console.WriteLine("Begin of {0}", "First"); Thread.Sleep(5000); Console.WriteLine("End of {0}", "First"); }); Console.WriteLine("Main thread exits."); Console.ReadKey(); } } }
範例03.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ThreadPoo { public class TaskInfo { public string Who; public TaskInfo(string Value) { Who = Value; } } class ThreadPool2 { static void Main(string[] args) { TaskInfo ti = new TaskInfo("Jack"); ThreadPool.QueueUserWorkItem(new WaitCallback(MyThreadWork), ti); Thread.Sleep(1000); Console.WriteLine("Main thread exits."); Console.ReadKey(); } static void MyThreadWork(object state) { TaskInfo ti = (TaskInfo)state; Console.WriteLine("Begin of {0}", ti.Who); Thread.Sleep(5000); Console.WriteLine("End of {0}", ti.Who); } } }
輸出結果 :
Begin of Jack Main thread exits. End of Jack
範例04.
using System.Threading; namespace TestThreadPool { class Program { static void Main(string[] args) { Console.WriteLine("以下開始將工作排入執行緒管理工作佇列 !!"); Console.WriteLine("***********************************************"); for (int n1 = 0; n1 < 3; n1++) { //建立 WaitCallback 物件,並且指定回呼方法 WaitCallback myWaitCallback = new WaitCallback(WorkA); //將 WaitCallback 排入排程 ThreadPool.QueueUserWorkItem(myWaitCallback, n1 + 1); //使畫面慢慢輸出 Thread.Sleep(1000); } Console.WriteLine("*********************************************"); for (int n1 = 0; n1 < 3; n1++) { ThreadPool.QueueUserWorkItem(new WaitCallback(WorkB), n1 + 1); Thread.Sleep(1000); } Console.WriteLine("***********************************"); for (int n1 = 0; n1 < 3; n1++) { ThreadPool.QueueUserWorkItem(new WaitCallback(WorkC), n1 + 1); Thread.Sleep(1000); } Console.ReadLine(); } public static void WorkA(object o) { string Name; //取得執行緒的雜湊碼 Name = "使用的執行緒編號 Thread ID# = " + Thread.CurrentThread.GetHashCode(); Console.WriteLine ("這是第一組被排入佇列的第 {0} 個工作,{1}", o, Name); Console.WriteLine("此工作執行緒結束 !! "); } public static void WorkB(object o) { string Name; Name = "使用的執行緒編號 Thread ID# = " + Thread.CurrentThread.GetHashCode(); Console.WriteLine ("這是第二組被排入佇列的第 {0} 個工作,{1}", o, Name); Console.WriteLine("此工作執行緒暫停 2 秒 !! "); Thread.Sleep(2000); } public static void WorkC(object o) { string Name; Name = "使用的執行緒編號 Thread ID# = " + Thread.CurrentThread.GetHashCode(); Console.WriteLine ("這是第三組被排入佇列的第 {0} 個工作,{1}", o, Name); Console.WriteLine("此工作執行緒暫停 10 秒 !! "); Thread.Sleep(10000); } } }
3 thoughts on “C# ThreadPool/線程池(執行序池)”
https://bbs.csdn.net/topics/230021205
1、線程池主要用於減少因頻繁創建和銷毀線程帶來開銷,因此那些經常使用且執行時間短的線程才需要用線程池來管理,用ThreadPool即可。
2、執行時間較長而又不經常出現的任務,可以單獨開闢線程處理,這類任務使用線程池並不會帶來明顯的性能提升,甚至有可能造成資源浪費。
3、執行時間較長,但經常出現的任務,需要綜合考慮具體執行的時間和出現頻度,以及自己編寫線程管理的複雜度來衡量;一般情況下,我認為單獨開闢線
就好。
4、實際作項目時,別忘了不同的機器,性能不一樣,多線程處理能力也是不一樣的。
//ThreadPool目標是為了減除線程的初始化開銷,實現並行處理。.NET類庫中的ThreadPool是異步IO的基礎,比如,在System.Net.Socket中,我們可以使用BeginAccept , EndAccept將Socket需要阻塞的操作放到系統的線程池中運行,而在執行結束以後通知主線程。
//我們的程序中使用ThreadPool來進行一些比較耗時或者需要阻塞的操作。當學要復雜的同步技術,例如事件,或需要對一個現場表調用Join方法時線程池就不能滿足需求了.在以下情況中不宜使用ThreadPool而應該使用單獨的Thread:
//1,需要為線程指定詳細的優先級
//2,線程執行需要很長時間
//3,需要把線程放在單獨的線程apartment中
//4,在線程執行中需要對線程操作,如打斷,掛起等。
搜來的,呵呵~
許多應用程序創建的線程都要在休眠狀態中消耗大量時間,以等待事件發生。其他線程可能進入休眠狀態,只被定期喚醒以輪詢更改或更新狀態信息。線程池通過為應用程序提供一個由系統管理的輔助線程池使您可以更為有效地使用線程。一個線程監視排到線程池的若干個等待操作的狀態。當一個等待操作完成時,線程池中的一個輔助線程就會執行對應的回調函數。
託管線程池中的線程為後台線程,即它們的IsBackground 屬性為true。這意味著在所有的前台線程都已退出後,ThreadPool 線程不會讓應用程序保持運行。
也可以將與等待操作不相關的工作項排列到線程池。若要請求由線程池中的一個線程來處理工作項,請調用QueueUserWorkItem 方法。此方法將對將被從線程池中選定的線程調用的方法或委託的引用用作參數。一個工作項排入隊列後就無法再取消它。
計時器隊列中的計時器以及已註冊的等待操作也使用線程池。它們的回調函數也會排列到線程池。
每個進程都有一個線程池。線程池的默認大小為每個可用處理器有25 個線程。使用SetMaxThreads 方法可以更改線程池中的線程數。每個線程使用默認的堆棧大小並按照默認的優先級運行。