接上文 多線程編程學習筆記-基礎(一) 五、終止線程 (Abort) 1.代碼如下 2.程式執行結果如下 從結果中,可以看出來,程式先啟動了子線程的列印數字方法,在運行了6秒之後,調用了abort方法,終止了子線程。但是這個abort是通過註入ThreadAbortException方法,從而使用線 ...
接上文 多線程編程學習筆記-基礎(一)
五、終止線程 (Abort)
1.代碼如下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; //引入線程 namespace ThreadConsoleApp { class Program { static void Main(string[] args) { Console.WriteLine("開始"); Thread t = new Thread(PrintNumberDely); //啟動線程 t.Start(); Thread.Sleep(TimeSpan.FromSeconds(6)); //線程終止 t.Abort(); Console.WriteLine("線程終止"); Console.WriteLine("啟動新線程"); t = new Thread(PrintNumber); t.Start(); PrintNumber(); Console.Read(); } static void PrintNumber() { Console.WriteLine("第四個多線程程式開始。。。。Second:" + DateTime.Now.Second); for (int i = 0; i <10; i++) { Console.WriteLine(string.Format("{0}",i)); } } /// <summary> /// 暫停2秒的方法 /// </summary> static void PrintNumberDely() { Console.WriteLine("第一個多線程終止程式開始。。。。"); for (int i = 0; i < 10; i++) { Console.WriteLine(string.Format("Second:{0} == {1}", DateTime.Now.Second, i)); Thread.Sleep(TimeSpan.FromSeconds(2)); } } } }
2.程式執行結果如下
從結果中,可以看出來,程式先啟動了子線程的列印數字方法,在運行了6秒之後,調用了abort方法,終止了子線程。但是這個abort是通過註入ThreadAbortException方法,從而使用線程終止,這種方法非常危險,不建議使用。在子線程終止之後,主線程繼續運行。
六、檢測線程狀態(ThreadState)
1.代碼如下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; //引入線程 namespace ThreadConsoleApp { class Program { static void Main(string[] args) { Console.WriteLine("開始"); Thread t = new Thread(PrintNumberStatus); Thread t2 = new Thread(DoNothing); //啟動線程 t2.Start(); t.Start(); //顯示線程狀態 for (int i = 0; i < 10; i++) { Thread.Sleep(TimeSpan.FromMilliseconds(300)); Console.WriteLine(t.ThreadState.ToString()); } Thread.Sleep(TimeSpan.FromSeconds(4)); //線程終止 t.Abort(); Console.WriteLine("線程終止"); Console.WriteLine(string.Format("t線程狀態:{0}", t.ThreadState.ToString())); Console.WriteLine(string.Format("t2線程狀態:{0}", t2.ThreadState.ToString())); Console.Read(); } static void DoNothing() { Console.WriteLine("第五個多線程程式開始。。。。Second:" + DateTime.Now.Second); Thread.Sleep(TimeSpan.FromSeconds(2)); } /// <summary> /// 暫停2秒的方法 /// </summary> static void PrintNumberStatus() { Console.WriteLine("第五個多線程檢測狀態程式開始。。。。" + Thread.CurrentThread.ThreadState.ToString()); for (int i = 0; i < 10; i++) { Console.WriteLine(string.Format("Second:{0} == {1}", DateTime.Now.Second, i)); Thread.Sleep(TimeSpan.FromSeconds(2)); } } } }
2.程式執行結果如下
如上圖,主線程啟動時定義了兩個子線程,一個會被終止,另一個會運行至結束。當我們啟動了線程之後,t2線程的狀態就會變成Running,然後會變成WaitSleepJoin,直到運行結束,變成Stopped。另一個t線程則會列印出數字來,當我們調用了abort方法之後,則t線程的狀態就變成了AbortRequested。這充分說明瞭同步兩個線程的複雜性,請不要程式中使用abort來終止線程。
七、線程優先順序(Priority)
1.代碼如下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; //引入線程 using System.Diagnostics; namespace ThreadConsoleApp { class Program { static void Main(string[] args) { Console.WriteLine("開始,當前線程的優先順序:"+Thread.CurrentThread.Priority); Console.WriteLine("線程運行多核CPU上"); //啟動線程 Run(); Thread.Sleep(TimeSpan.FromSeconds(2)); //單核模擬 Console.WriteLine("線程運行單核CPU上"); Process.GetCurrentProcess().ProcessorAffinity = new IntPtr(1); Run(); Console.Read(); } static void Run() { var demo = new ThreadRunDemo(); Thread thread1 = new Thread(demo.CountNumber); thread1.Name = "ThreadOne"; Thread thread2 = new Thread(demo.CountNumber); thread2.Name = "ThreadTwo"; thread2.Priority = ThreadPriority.BelowNormal; Thread thread3 = new Thread(demo.CountNumber); thread3.Name = "ThreadThree"; thread1.Priority = ThreadPriority.Highest; thread2.Priority = ThreadPriority.AboveNormal; thread3.Priority = ThreadPriority.Lowest; thread1.Start(); thread2.Start(); thread3.Start(); Thread.Sleep(2000); demo.Stop(); } } class ThreadRunDemo { private bool isStopped = false; public void Stop() { isStopped = true; } public void CountNumber() { long cnt = 0; while(!isStopped) { cnt++; } Console.WriteLine(string.Format("線程 {0} 的優先順序 {1,11} ,一共計算了 {2,13} 數字",
Thread.CurrentThread.Name,Thread.CurrentThread.Priority.ToString(), cnt.ToString("N0"))); } } }
2.程式執行結果如下
從上圖的結果中,看出來當在多核CPU上運行多線程程式時,優先順序所起到的作用區別不大,以上圖的結果來看,最高優先順序與最低優先順序之間的差別在10%左右。如果在單核CPU上運行多線程程式時,優先順序的作用的特別明顯,以上圖的結果來看,最高優先順序與最低優先順序之間的差別在100倍以上。
八、前臺線程與後臺線程
1.代碼如下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; //引入線程 using System.Diagnostics; namespace ThreadConsoleApp { class Program { static void Main(string[] args) { Console.WriteLine("開始,前臺線程與後臺線程"); var fore = new ThreadBackground(10); var back = new ThreadBackground(20); Thread threadF = new Thread(fore.CountNumber); threadF.Name = "前臺線程"; Thread threadB = new Thread(back.CountNumber); threadB.Name = "後臺線程"; threadB.IsBackground = true; //啟動線程 threadF.Start(); threadB.Start(); //Console.Read(); } } class ThreadBackground { private int cnt ; public ThreadBackground(int count) { cnt = count; } public void CountNumber() { for (int i = 0; i < cnt; i++) { Thread.Sleep(500); Console.WriteLine(string.Format("線程 {0} 列印 {1,11} 數字", Thread.CurrentThread.Name, i.ToString("N0"))); } Console.WriteLine("{0} finished counting.", Thread.CurrentThread.IsBackground ? "Background Thread" : "Foreground Thread"); } } }
2.程式執行結果
根據上面的代碼,當程式執行到如上圖時,會一閃而過,退出。這是因為前臺線程已經執行結束,雖然後臺線程沒有執行結束,但程式會自動終止後臺線程。這就是前臺線程與後臺線程的區別,進程會等所有的前臺線程執行完畢,如果此時只剩下後臺線程沒有執行完畢,則會直接結束工作。