創建線程
線程的基本操作
線程和其它常見的類一樣,有着很多屬性和方法,參考下表:
創建線程的方法有很多種,這里我們先從thread開始創建線程
class Program { static void Main(string[] args) { Thread t = new Thread(PrintNumbers); t.Start(); PrintNumbers(); } static void PrintNumbers() { Console.WriteLine("Starting..."); for (int i = 0; i < 10; i++) { Console.WriteLine(i); } } }
Thread構造函數接受兩種委托
public delegate void ThreadStart(); 無返回值、無參的 public delegate void ParameterizedThreadStart(object obj);無返回值、參數為object類型的方法
既然構造函數是委托那么我還可以用lambda來簡寫
Thread t = new Thread(()=> { Console.WriteLine("Starting..."); for (int i = 0; i < 10; i++) { Console.WriteLine(i); } }); t.Start();
很多時候我們都需要線程執行的是一個有參的方法,下面看看如何調用有多個參數的方法,
static void Main(string[] args) { int b = 10; string c = "主線程"; Thread t = new Thread(()=> PrintNumbers(b,c)); t.Start(); } static void PrintNumbers(int count,string name) { for (int i = 0; i < count; i++) { Console.WriteLine("name:{0},i:{1}",name,i); } }
Thread.Join()
我的理解是當調用Join()方法時主線程會停止工作,我不干活了,等你干完了我在繼續干活如:
static void Main(string[] args) { Thread.CurrentThread.Name = "主線程"; Console.WriteLine("線程名字:{0},線程工作狀態:{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState); Thread abortThread = new Thread(AbortMethod); abortThread.Name = "子線程"; abortThread.Start(); abortThread.Join(); Console.WriteLine("線程名字:{0},子線程工作狀態:{1}", abortThread.Name, abortThread.ThreadState); Console.WriteLine("繼續干活"); Console.Read(); } private static void AbortMethod() { Console.WriteLine("線程名字:{0},子線程工作狀態:{1}",Thread.CurrentThread.Name,Thread.CurrentThread.ThreadState); for (int i = 0; i < 5; i++) { Thread.Sleep(1000); Console.WriteLine(i); } }
//輸出結果
線程名字:主線程,線程工作狀態:Running
線程名字:子線程,子線程工作狀態:Running
0
1
2
3
4
線程名字:子線程,子線程工作狀態:Stopped
繼續干活
Thread.Abort()
Abort()方法來終止線程的運行,我們在使用它的時候要主要,它是通過拋出ThreadAbortException異常的方式來終止線程的
static void Main(string[] args) { Thread abortThread = new Thread(AbortMethod); abortThread.Name = "test"; abortThread.Start(); Thread.Sleep(3000); try { abortThread.Abort(); } catch(Exception e) { Console.WriteLine("主線程:{0}", Thread.CurrentThread.Name); } Console.WriteLine("我被開除了,子線程:{0},子線程狀態:{1}", abortThread.Name, abortThread.ThreadState); Console.Read(); } private static void AbortMethod() { try { Console.WriteLine("子線程:{0},子線程狀態:{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState); Console.WriteLine("開始干活"); for (int i = 0; i < 5; i++) { Thread.Sleep(1000); Console.WriteLine(i); } Console.WriteLine("繼續干活"); } catch (Exception e) { Console.WriteLine("類型:"+e.GetType().Name); Console.WriteLine("子線程:{0},子線程狀態:{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState); } } 輸出 子線程:test,子線程狀態:Running 開始干活 0 1 類型:ThreadAbortException 子線程:test,子線程狀態:AbortRequested 我被開除了,子線程:test,子線程狀態:Aborted
從運行結果可以看出,調用Abort方法的線程引發的異常類型為ThreadAbortException, 以及異常只會在 調用Abort方法的線程中發生,而不會在主線程中拋出,並且調用Abort方法后線程的狀態不是立即改變為Aborted狀態,而是從AbortRequested->Aborted。
Thread.ResetAbort()
Abort方法可以通過跑出ThreadAbortException異常中止線程,而使用ResetAbort方法可以取消中止線程的操作,下面通過代碼演示使用 ResetAbort方法
static void Main(string[] args) { Thread abortThread = new Thread(AbortMethod); abortThread.Name = "test"; abortThread.Start(); Thread.Sleep(1000); try { abortThread.Abort(); } catch(Exception e) { Console.WriteLine("主線程:{0}", Thread.CurrentThread.Name); } Console.WriteLine("我被開除了,子線程:{0},子線程狀態:{1}", abortThread.Name, abortThread.ThreadState); Console.Read(); } private static void AbortMethod() { try { Console.WriteLine("我要被開除了"); for (int i = 0; i < 5; i++) { Thread.Sleep(1000); Console.WriteLine(i); } } catch (Exception e) { Thread.ResetAbort(); Console.WriteLine("類型:"+e.GetType().Name); Console.WriteLine("子線程:{0},子線程狀態:{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState); } Console.WriteLine("我又回來繼續干活"); } 輸出 我要被開除了 我被開除了,子線程:test,子線程狀態:AbortRequested 類型:ThreadAbortException 子線程:test,子線程狀態:Running 我又回來繼續干活
線程的優先級
如果在應用程序中有多個線程在運行,但一些線程比另一些線程重要,這種情況下可以在一個進程中為不同的線程指定不同的優先級。線程的優先級可以通過Thread類Priority屬性設置,Priority屬性是一個ThreadPriority型枚舉,列舉了5個優先等級:AboveNormal、BelowNormal、Highest、Lowest、Normal。公共語言運行庫默認是Normal類型的。見下圖: