.NetFramework1.0時代的Thread,API功能繁多,對線程的數量是沒有管控的,在.NetFramework2.0時代推出了ThreadPool,若是某個對象建立和銷燬代價比較高,同時這個對象還能夠反覆使這些線程,就須要使用線程池,線程池能夠保存多個線程對象,須要使用線程時直接從線程池裏面拿,使用完以後不作釋放,又放回池子(享元模式),須要用的時候再去拿。這樣能夠減小建立線程的開銷,提高性能,此外,還能夠管控線程的總數量,防止資源濫用。數組
委託異步調用、Task、Parrallel、async/await的線程所有都是線程池裏面的線程。直接new Thread開起的線程不受線程池的數量限制(可是會佔用線程池的線程數量)。異步
ThreadPool.QueueUserWorkItem(o=>this.DoSomeThing("btnThreadPool_Click_1")); ThreadPool.QueueUserWorkItem(o => { this.DoSomeThing("btnThreadPool_Click_2"); Console.WriteLine( o?.ToString()); }, "wjl");
I/O線程是.NET專爲訪問外部資源所設置的一種線程,由於訪問外部資源經常要受到外界因素的影響,爲了防止讓主線程受影響而長期處於阻塞狀態,.NET爲多個I/O操做都創建起了異步方法。async
//檢索由 GetMaxThreads 返回的線程池線程的最大數目和異步IO線程的最大數目 ThreadPool.GetMaxThreads(out int workerThreads, out int completionPortThreads); Console.WriteLine($"當前線程池最大數目爲:{workerThreads},最大異步IO線程:{completionPortThreads}"); //檢索由 GetMinThreads 返回的線程池線程的最小數目和異步IO線程的最小數目 ThreadPool.GetMinThreads(out int workerThreadsMin, out int completionPortThreadsMin); Console.WriteLine($"當前線程池最小數目爲:{workerThreadsMin},最小異步IO線程:{completionPortThreadsMin}"); ThreadPool.SetMaxThreads(8, 8);//設置的最大值,必須大於CPU核數,不然設置無效 ThreadPool.SetMinThreads(2, 2);
單個線程等待:函數
//線程等待 ManualResetEvent mre = new ManualResetEvent(false); //ManualResetEvent是一種信號量的方式 //若是初始爲false--關閉, mre.Set()以後變爲ture,WaitOne就能經過 //若是初始爲tue--打開, mre.Rset()以後變爲false,WaitOne就只能等待 ThreadPool.QueueUserWorkItem(o => { this.DoSomeThing("btnThreadPool_Click_3"); mre.Set(); }); mre.WaitOne(); Console.WriteLine("任務已經完成了...");
多個線程等待:性能
ManualResetEvent[] mres = new ManualResetEvent[10]; for (int i = 0; i < 10; i++) { mres[i] = new ManualResetEvent(false); int k = i; ThreadPool.QueueUserWorkItem(o => { this.DoSomeThing($"mres{k}"); ManualResetEvent mre = o as ManualResetEvent; mre.Set(); }, mres[i]); } //等待全部數組中的元素都收到信號,若是是控制檯程序或者winform程序,請將Main()函數上面的特性[STAThread]註釋掉 WaitHandle.WaitAll(mres); Console.WriteLine("多個任務已經完成了...");