//1 thread:線程等待,回調,前台線程/后台線程 //2 threadpool:線程池使用,設置線程池,ManualResetEvent //3 擴展封裝thread&threadpool回調/等待 class Program { static void Main(string[] args) { //ThreadTest threadTest = new ThreadTest(); //threadTest.ThreadShow(); ThreadPoolTest threadPoolTest = new ThreadPoolTest(); threadPoolTest.ThreadPoolShow(); Console.ReadLine(); } }
/// 多線程1.0 /// Thread:C#對線程對象的一個封裝 public class ThreadTest { public void ThreadShow() { Console.WriteLine($"**************** Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************"); //{ // //執行無參數的委托 // ThreadStart method = () => // { // DoSomething.DoSomethingLong("張三"); // }; // Thread thread = new Thread(method); // thread.Start(); ;//開啟線程,執行委托的內容 // //thread.Suspend(); //已啟用,暫停線程 // //thread.Resume(); //已棄用,恢復線程 // //thread.Abort(); //停止線程 線程是計算機資源,程序想停下線程,只能向操作系統通知(線程拋異常),會有延時/不一定能真的停下來 // //1.等待 // //while (thread.ThreadState != ThreadState.Stopped) //根據線程狀態判斷 // //{ // // Thread.Sleep(200);//當前線程休息200ms // //} // //2.Join等待 // //thread.Join(); // //thread.Join(1000);//最多等待1000ms // //Console.WriteLine("線程完成之后的操作"); // //thread.Priority = ThreadPriority.Highest; // //最高優先級:優先執行,但不代表優先完成 甚至說極端情況下,還有意外發生,不能通過這個來控制線程的執行先后順序 // // thread.IsBackground = false;//默認是false 前台線程,進程關閉,線程需要計算完后才退出 // // thread.IsBackground = true;//關閉進程,線程退出 //} //{ // //執行帶參數的委托 // ParameterizedThreadStart method = (o) => // { // DoSomething.DoSomethingLong(o.ToString()); // }; // Thread thread = new Thread(method); // thread.Start("張三"); ;//開啟線程,執行委托的內容 //} //Action action = () => //{ // Thread.Sleep(2000); // Console.WriteLine("線程執行完回調方法"); //}; //ThreadStart method = () => //{ // DoSomething.DoSomethingLong("張三"); //}; //this.ThreadWithCallBack(method, action); Func<int> method = () => { Thread.Sleep(2000); return 123; }; Func<int> funcThread = this.ThreadWithReturn(method);//非阻塞 //Console.WriteLine("do something else/////"); //Console.WriteLine("do something else/////"); //Console.WriteLine("do something else/////"); //Console.WriteLine("do something else/////"); //Console.WriteLine("do something else/////"); int iResult = funcThread.Invoke();//當獲取值的時候會阻塞 Console.WriteLine(iResult); Console.WriteLine($"**************** End {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************"); } //基於thread封裝一個回調 //回調:啟動子線程執行動作A--不阻塞--A執行完后子線程會執行動作B /// <summary> /// /// </summary> /// <param name="threadStart">多線程執行的操作</param> /// <param name="actionCallback">線程完成后,回調的動作</param> public void ThreadWithCallBack(ThreadStart threadStart, Action actionCallback) { ThreadStart start = new ThreadStart(() => { threadStart.Invoke(); actionCallback.Invoke(); }); new Thread(start).Start(); } /// <summary> /// 1 異步,非阻塞的 /// 2 還能獲取到最終計算結果 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="func"></param> /// <returns></returns> private Func<T> ThreadWithReturn<T>(Func<T> func) { T t = default(T); ThreadStart start = new ThreadStart(() => { t = func.Invoke(); }); Thread thread = new Thread(start); thread.Start(); return new Func<T>(() => { thread.Join(); return t; }); } }
/// /// 線程池.NetFramework2.0 /// 如果某個對象創建和銷毀代價比較高,同時這個對象還可以反復使用的,就需要一個池子 /// 保存多個這樣的對象,需要用的時候從池子里面獲取;用完之后不用銷毀,放回池子 /// 節約資源提升性能;此外,還能管控總數量,防止濫用; /// /// ThreadPool的線程都是后台線程 /// public class ThreadPoolTest { public void ThreadPoolShow() { //開啟線程執行委托 //ThreadPool.QueueUserWorkItem(o => //{ // Console.WriteLine("123"); //}); //ThreadPool.GetMaxThreads(out int workerThreads, out int completionPortThreads); //Console.WriteLine($"當前電腦最大workerThreads={workerThreads} 最大completionPortThreads={completionPortThreads}"); //ThreadPool.GetMinThreads(out int workerThreadsMin, out int completionPortThreadsMin); //Console.WriteLine($"當前電腦最小workerThreads={workerThreadsMin} 最大completionPortThreads={completionPortThreadsMin}"); ////設置的線程池數量是進程全局的, ////委托異步調用--Task--Parrallel--async/await 全部都是線程池的線程 ////直接new Thread不受這個數量限制的(但是會占用線程池的線程數量) 如果線程池數量已用完還是可以new Thread,如果先new Thread 會占用線程池數量 //ThreadPool.SetMaxThreads(8, 8);//設置的最大值,必須大於CPU核數,否則設置無效 //ThreadPool.SetMinThreads(2, 2); //Console.WriteLine("&&&&&&&&&&&&&&&&&&&&&&&設置最大最小&&&&&&&&&&&&&&&&&&&&&&&&&&&"); //ThreadPool.GetMaxThreads(out int workerThreads1, out int completionPortThreads1); //Console.WriteLine($"當前電腦最大workerThreads={workerThreads1} 最大completionPortThreads={completionPortThreads1}"); //ThreadPool.GetMinThreads(out int workerThreadsMin1, out int completionPortThreadsMin1); //Console.WriteLine($"當前電腦最大workerThreads={workerThreadsMin1} 最大completionPortThreads={completionPortThreadsMin1}"); { //等待 ManualResetEvent mre = new ManualResetEvent(false); //false---關閉---Set打開---true---WaitOne就能通過 //true---打開--ReSet關閉---false--WaitOne就只能等待 ThreadPool.QueueUserWorkItem(o => { DoSomething.DoSomethingLong("btnThreadPool_Click1"); mre.Set(); }); Console.WriteLine("Do Something else..."); Console.WriteLine("Do Something else..."); Console.WriteLine("Do Something else..."); mre.WaitOne(); Console.WriteLine("任務已經完成了。。。"); } } }