線程是一個獨立的運行單元,每一個進程內部有多個線程,每一個線程能夠各自同時執行指令。每一個線程有本身獨立的棧,可是與進程內的其餘線程共享內存。對某些程序來講,其中有一個線程是特殊的,例如:Console的main
線程和窗體程序的UI
線程。git
每一個.NET
程序都有一個線程池,線程池維護着必定數量的工做線程,這些線程等待着執行分配下來的任務,線程池能夠隨時監測線程的數量。配置線程池的參數不少。可是我都建議你們使用默認值,這些值都是通過微軟調試好的,能夠知足大部分應用。github
線程是低級別的抽象,線程池雖然高級一點,但一樣很低,而如今C#給咱們提供了不少高級的併發編程技術工具,因此原則上咱們不建議直接操做
Thread
對象。可是爲了讓你們很好的理解C#多線程的前因後果,這裏介紹C#最初操做多線程的方法。
因爲寫博客我喜歡用Mac
,因此個人例程是用.net core
框架,使用 VS Code
開發,源碼發佈到github中,連接:spartajet/CSharpLearnBlog編程
首先,咱們要建立一個新建線程中運行的方法,主要是打印數字,以下:c#
/// <summary> /// 數數方法 /// </summary> static void NumberCount(){ for (int i = 0; i < 10; i++) { Console.WriteLine($"The number is {i}"); } }
在 main
方法中添加以下代碼來開啓一個線程多線程
static void Main(string[] args) { Thread workThread=new Thread(NumberCount); workThread.Start(); NumberCount(); }
運行結果,以下:併發
The number is 0 The number is 0 The number is 1 The number is 2 The number is 3 The number is 4 The number is 5 The number is 6 The number is 7 The number is 8 The number is 9 The number is 1 The number is 2 The number is 3 The number is 4 The number is 5 The number is 6 The number is 7 The number is 8 The number is 9
能夠看出,C#的多線程執行順序是不肯定的。NumberCount
方法同時被工做線程和主線程調用,能夠看到工做線程和主線程是同步運行的,互不干擾。框架
Thread
的聲明還有其餘方式,可使用Lambda
風格來定義。方法以下:工具
var workThread=new Thread(() => { for (int i = 0; i < 10; i++) { Console.WriteLine($"The number is {i}"); } });
暫停一個線程是讓一個線程等待一段時間而不消耗操做系統資源。 測試
將方法NumberCount
修改成:this
/// <summary> /// 數數方法 /// </summary> static void NumberCountCouldDelay(){ for (int i = 0; i < 10; i++) { Console.WriteLine($"The number is {i}"); Thread.Sleep(TimeSpan.FromSeconds(1)); } }
運行結果爲:
The number is 0 The number is 0 The number is 1 The number is 1 The number is 2 The number is 2 The number is 3 The number is 3 The number is 4 The number is 4 The number is 5 The number is 5 The number is 6 The number is 6 The number is 7 The number is 7 The number is 8 The number is 8 The number is 9 The number is 9
你們能夠看到,方法改動只是增長了一行
Thread.Sleep(TimeSpan.FromSeconds(1));
Thread.Sleep
方法被調用後,線程處於休眠狀態,會盡量的少佔用系統資源,起到了暫停線程的效果。
線程等待是指多線程編程中,一個線程等待另外一個線程完成後再執行。
代碼以下:
static void Main(string[] args) { var workThread=new Thread(NumberCountCoudDelay); workThread.Start(); workThread.Join(); NumberCount(); } /// <summary> /// 數數方法 /// </summary> static void NumberCountCoudDelay(){ for (int i = 0; i < 10; i++) { Console.WriteLine($"Delay thread number is {i}"); Thread.Sleep(TimeSpan.FromSeconds(1)); } } /// <summary> /// 數數方法 /// </summary> static void NumberCount(){ for (int i = 0; i < 10; i++) { Console.WriteLine($"Main thread number is {i}"); Thread.Sleep(TimeSpan.FromSeconds(1)); } }
運行結果:
Delay thread number is 0 Delay thread number is 1 Delay thread number is 2 Delay thread number is 3 Delay thread number is 4 Delay thread number is 5 Delay thread number is 6 Delay thread number is 7 Delay thread number is 8 Delay thread number is 9 Main thread number is 0 Main thread number is 1 Main thread number is 2 Main thread number is 3 Main thread number is 4 Main thread number is 5 Main thread number is 6 Main thread number is 7 Main thread number is 8 Main thread number is 9
能夠看出來,咱們使用了 Join
方法,該方法容許咱們等待知道此線程完成,當線程完成後,下面的代碼才能夠執行。
結束線程是指在某個線程運行中間中止該線程。
代碼以下:
static void Main(string[] args) { var workThread=new Thread(NumberCountCoudDelay); workThread.Start(); Thread.Sleep(TimeSpan.FromSeconds(4)); workThread.Abort(); Console.WriteLine("Work thread is stopped!!!"); }
結果以下:
Delay thread number is 0 Delay thread number is 1 Delay thread number is 2 Delay thread number is 3 Unhandled Exception: Delay thread number is 4 System.PlatformNotSupportedException: Thread abort is not supported on this platform. at System.Threading.Thread.Abort() at CSharpAsync.Program.Main(String[] args) in /Users/spartajet/CodeWorkSpace/VSCode/CSharpLearnBlog/CSharpAsync/Program.cs:line 12
爲何會出現這個現象呢,請參照:Methods that throw PlatformNotSupportedException are not documented
能夠看出.net core
對 Thread
的支持不夠,是由於 Thread
已經徹底落伍了,一樣在Windows
咱們也不建議這麼作。
方法代碼以下:
public void Abort() { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ThreadAbort); } public void Abort(object stateInfo) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ThreadAbort); } public static void ResetAbort() { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ThreadAbort); } [Obsolete("Thread.Suspend has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. http://go.microsoft.com/fwlink/?linkid=14202", false)] public void Suspend() { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ThreadSuspend); }
可是在Windows
平臺這段代碼是徹底可行的。
一個線程能夠用 ThreadState
枚舉來表示,
下面是ThreadState
的源碼:
public enum ThreadState { Running = 0, StopRequested = 1, SuspendRequested = 2, Background = 4, Unstarted = 8, Stopped = 16, // 0x00000010 WaitSleepJoin = 32, // 0x00000020 Suspended = 64, // 0x00000040 AbortRequested = 128, // 0x00000080 Aborted = 256, // 0x00000100 }
測試代碼以下:
static void Main(string[] args) { var workThread=new Thread(NumberCountCoudDelay); Console.WriteLine($"work thread state: {workThread.ThreadState}"); workThread.Start(); workThread.Join(); Console.WriteLine($"work thread state: {workThread.ThreadState}"); Console.WriteLine("Work thread is stopped!!!"); }
結果以下:
work thread state: Unstarted Delay thread number is 0 work thread state: Running Delay thread number is 1 work thread state: Running Delay thread number is 2 work thread state: Running Delay thread number is 3 work thread state: Running Delay thread number is 4 work thread state: Running Delay thread number is 5 work thread state: Running Delay thread number is 6 work thread state: Running Delay thread number is 7 work thread state: Running Delay thread number is 8 work thread state: Running Delay thread number is 9 work thread state: Running work thread state: Stopped Work thread is stopped!!!