在多線程這一系列文章中,我們將講述C#語言中多線程的相關知識,在多線程(基礎篇)中我們將學習以下知識點:
一、創建線程
在整個系列文章中,我們主要使用Visual Studio 2015作為線程編程的主要工具。在C#語言中創建、使用線程只需要按以下步驟編寫即可:
1、啟動Visual Studio 2016,新建一個控制台應用程序。
2、確保該控制台程序使用.NET Framework 4.6或以上版本。然而在該篇中的所有示例使用較低版本可以正常工作。
3、雙擊打開該控制台應用程序中的“Program.cs”文件,在其中編寫如下代碼:
1 using System; 2 using System.Threading; 3 using static System.Console; 4 5 namespace Recipe01 6 { 7 class Program 8 { 9 static void PrintNumbers() 10 { 11 WriteLine("Starting..."); 12 for (int i = 1; i < 10; i++) 13 { 14 WriteLine(i); 15 } 16 } 17 18 static void Main(string[] args) 19 { 20 Thread t = new Thread(PrintNumbers); 21 t.Start(); 22 PrintNumbers(); 23 } 24 } 25 }
4、運行該控制台應用程序,運行效果(每次運行效果可能不同)如下圖所示:
在第2行代碼處,我們導入了System.Threading命名空間,該命名空間包含了我們編寫多線程程序所需要的所有類型。
在第3行代碼處,我們使用了C# 6.0的using static特性,使用了該特性之後,在代碼中允許我們在使用System.Console類型的靜態方法的時候不需要指定其類型名。
在第9~16行代碼處,我們定義了一個名為“PrintNumbers”的方法,該方法將在“Main”方法和線程中進行調用。
在第20行代碼處,我們創建了一個線程來運行“PrintNumbers”方法,當我們初始化一個線程時,一個“ThreadStart”或“ParameterizedThreadStart”委托的實例被傳遞給線程的構造方法。
在第21行代碼處,我們啟動線程。
在第22行代碼處,我們在“Main”方法中調用“PrintNumbers”方法。
二、中止線程
在這一節,我們將讓線程等待一些時間,在等待的這段時間內,該線程不會消耗操作系統的資源。編寫步驟如下:
1、使用Visual Studio 2015創建一個新的控制台應用程序。
2、雙擊打開“Program.cs”文件,編寫代碼如下所示:
1 using System; 2 using System.Threading; 3 using static System.Console; 4 using static System.Threading.Thread; 5 6 namespace Recipe02 7 { 8 class Program 9 { 10 static void PrintNumbers() 11 { 12 WriteLine("Starting..."); 13 14 for(int i = 1; i < 10; i++) 15 { 16 WriteLine(i); 17 } 18 } 19 20 static void PrintNumbersWithDelay() 21 { 22 WriteLine("Starting..."); 23 24 for(int i = 1; i < 10; i++) 25 { 26 Sleep(TimeSpan.FromSeconds(2)); 27 WriteLine(i); 28 } 29 } 30 31 static void Main(string[] args) 32 { 33 Thread t = new Thread(PrintNumbersWithDelay); 34 t.Start(); 35 PrintNumbers(); 36 } 37 } 38 }
3、運行該控制台應用程序,運行效果(每次運行效果可能不同)如下圖所示:
在第20~29行代碼處,我們定義了一個新的方法“PrintNumbersWithDelay”,該方法將在我們新建的線程中運行。需要注意的是在第26行代碼處,我們使用了“Thread”類的靜態方法“Sleep”,該方法使得每次循環都會等待2秒鐘執行。
在第33行代碼處,我們創建一個新的線程來運行“PrintNumbersWithDelay”方法。
三、線程等待
在這一節中,我們將講述如何在一個線程執行完畢後,再執行剩余的代碼,要完成這個工作,我們不能使用Thread.Sleep方法,因為我們不知道另一個線程精確的執行時間。要使一個線程等待另一個線程執行完畢後再進行其他工作,只需要按下列步驟編寫代碼即可:
1、使用Visual Studio 2015創建一個新的控制台應用程序。
2、雙擊打開“Program.cs”文件,編寫如下代碼:
1 using System; 2 using System.Threading; 3 using static System.Console; 4 using static System.Threading.Thread; 5 6 namespace Recipe03 7 { 8 class Program 9 { 10 static void PrintNumbersWithDelay() 11 { 12 WriteLine("Starting..."); 13 14 for(int i = 1; i < 10; i++) 15 { 16 Sleep(TimeSpan.FromSeconds(2)); 17 WriteLine(i); 18 } 19 } 20 21 static void Main(string[] args) 22 { 23 WriteLine("Starting..."); 24 Thread t = new Thread(PrintNumbersWithDelay); 25 t.Start(); 26 t.Join(); 27 WriteLine("Thread completed"); 28 } 29 } 30 }
3、運行該控制台應用程序,運行效果如下圖所示:
在第26行代碼處,我們在“Main”方法中調用調用“t.Join”方法,該方法允許我們等待線程t執行完畢後,再執行“Main”方法中剩余的代碼。有了該技術,我們可以同步兩個線程的執行步驟。第一個線程等待第二個線程執行完畢後,再進行其他的工作,在第一個線程等待期間,第一個線程的狀態為“bolcked”狀態,和我們調用Thread.Sleep的狀態一樣。
四、終止線程
在這一節中,我們將講述如何終止另一個線程的執行。步驟如下:
1、使用Visual Studio 2015創建一個新的控制台應用程序。
2、雙擊打開“Program.cs”文件,編寫如下代碼:
1 using System; 2 using System.Threading; 3 using static System.Console; 4 using static System.Threading.Thread; 5 6 namespace Recipe04 7 { 8 class Program 9 { 10 static void PrintNumbers() 11 { 12 WriteLine("Starting..."); 13 14 for (int i = 1; i < 10; i++) 15 { 16 WriteLine(i); 17 } 18 } 19 20 static void PrintNumbersWithDelay() 21 { 22 WriteLine("Starting..."); 23 for (int i = 1; i < 10; i++) 24 { 25 Sleep(TimeSpan.FromSeconds(2)); 26 WriteLine(i); 27 } 28 } 29 30 static void Main(string[] args) 31 { 32 WriteLine("Starting program..."); 33 Thread t = new Thread(PrintNumbersWithDelay); 34 t.Start(); 35 Thread.Sleep(TimeSpan.FromSeconds(6)); 36 t.Abort(); 37 WriteLine("A thread has been aborted"); 38 t = new Thread(PrintNumbers); 39 t.Start(); 40 PrintNumbers(); 41 } 42 } 43 }
3、運行該控制台應用程序,運行效果(每次運行效果可能不同)如下圖所示:
在第36行代碼處,我們調用了“t.Abort”方法,該方法用於終止一個線程的執行。當Abort方法被調用時,會對目標線程注入“ThreadAbortException”異常,該異常將導致線程的終止,這是一種非常危險的操作,因為這個異常可能發生在任何時候,並有可能導致整個應用程序的銷毀。因此,不推薦使用Abort方法來終止一個線程的執行,我們可以向線程提供一個“CancellationToken”對象來取消一個線程的執行,這個技術我們將在後續講述。
未完待續!