Thread類可以創建和控制線程,Thread類的構造函數重載為接受ThreadStart和ParameterizedThreadStart類型的委托參數。下面我們用一個例子來解釋怎樣用Thread類來創建一個簡單的線程
static void Main(string[] args) { #region Thread無參數舉例 Thread th = new Thread(ThreadChild); th.Start(); Console.WriteLine("Main Thread Start!"); #endregion } static void ThreadChild() { Console.WriteLine("Child Thread Start!"); }
輸出結果

程序運行的結果不能保證哪個先輸出,因為線程是由操作系統調度,每次哪個線程在前面可以不同
給線程傳遞數據
上面的例子演示了怎樣用Thread類來創建一個不帶傳參的線程,下面我門來創建一個帶傳入參數的線程。給線程傳遞參數,有兩種方式,一種是使用帶ParameterizedThreadStart委托參數的Thread的構造函數,另外一種是定義一個自定義類。首先我們使用ParameterizedThreadStart委托來創建有傳入參數的類。使用ParameterizedThreadStart,線程的入口(線程調用的方法)必須有一個Object類型的參數,使用Object我們首先想到的就是類型不安全。而且在執行線程的時候多半有裝箱拆箱操作。管它的,我們先用這種方式來創建一個帶傳入參數的線程!!
廢話再多,還是沒有直接上代碼來得實在,看代碼!!
static void Main(string[] args) { #region 使用parameterizedThreadStart委托執行帶參數的委托 Thread th2 = new Thread(Thread_param); th2.Start(20); #endregion } static void Thread_param(object msg) { int message = (int)msg; Console.WriteLine("Result:{0}",message); }
運行結果

上面創建的線程是類型不安全的,那用什么樣的方式執行帶傳入參數的線程的方法是類型安全的呢,答案就是創建一個自定義類,在類中定義一個作為傳入參數的字段,將線程的主方法定義為一個類的實例方法。然而使用這種方法就可以使用泛型來解決使用ParameterizedThreadStart的類型不安全
看招!!!!
class Program { static void Main(string[] args) { #region 使用自定義類實現帶參數的線程 MyThread<string> mythread = new MyThread<string>("Thread_child"); Thread th3 = new Thread(mythread.ThreadChild); th3.Start(); #endregion } } class MyThread<T> { private T data; public MyThread(T data) { this.data = data; } public void ThreadChild() { Console.WriteLine("Child Thread Start! Result:{0}",data); } }
運行結果:

后台線程
Thread類默認創建的是前台線程,所以我們前面創建的線程全部都是前台線程。只要有一個前台線程在運行,應用程序的進程就在運行。如果有多個前台線程在運行,而Main()方法(主線程)結束了,應用程序的進程就仍然是激活的,直到所有前台線程完成其任務為止。
那后台線程呢?顯然和前台線程相反。當主線程結束后,應用程序的進程就終止了,在所有前台線程結束后,后台線程就會被終止。
在編碼的時候我們可以設置Thread類的IsBackground的屬性來確定該線程是前台線程還是后台線程。當IsBackground設置為False的時候,為前台線程,設置為Ture的時候為后台線程,下面我們舉例來說明前台線程和后台線程的區別。首先我們創建一個前台線程。
static void Main(string[] args) { Thread th_pre = new Thread(Thread_pre) {Name="Thread_pre",IsBackground=flase};; th_pre.Start(); Console.WriteLine("主線程執行完成!"); } static void Thread_pre() { Console.WriteLine("子線程開始執行!"); Thread.Sleep(3000); Console.WriteLine("子線程執行完成!"); }
運行結果

從上面的運行結果可以看到,當主線程執行完成后,應用程序終止前就會子線程執行完成。
下面我們來看看后台線程,看代碼!!
static void Main(string[] args) { Thread th_back = new Thread(Thread_back) { Name="Thread_back",IsBackground=true }; th_back.Start(); Console.WriteLine("主線程執行完成!"); } static void Thread_back() { Console.WriteLine("子線程開始執行!"); Thread.Sleep(3000); Console.WriteLine("子線程執行完成!"); }
運行結果

從運行結果可以看出,當主線程結束后,進程就終止了,后台線程也被終止,所以沒有后台線程結束的輸出信息。
控制線程
我們使用Thread創建線程后,我們需要對線程進行控制。
1、 使用Start()方法使線程處於Running狀態,線程開始執行。
2、 使用Join()方法使線程處於WaitSleepJoin狀態,在繼續執行標准的 COM 和 SendMessage 消息泵處理期間,阻塞調用線程,直到某個線程終止或經過了指定時 間為止。
3、 使用Sleep()方法,也會使線程處於WaitSleepJoin狀態,在經歷Sleep()方法定義的時間段后,線程就會被再次喚醒。、
4、 使用Abort()方法,會使線程處於ResetAbort()狀態,線程在接到這個命令的時候,會拋出一個ThradAbordException類型的異常。
各位看官,看代碼
using System; using System.Text; using System.Threading; namespace ConsoleThreadContral { class Program { static void Main(string[] args) { Console.WriteLine("mainThread Start!"); Thread th = new Thread(newThread); th.Start();//將當前實例的狀態更改為 ThreadState.Running。 Console.WriteLine("newThread State:{0}",th.ThreadState); th.Join(100);//在繼續執行標准的 COM 和 SendMessage 消息泵處理期間,阻塞調用線程,直到某個線程終止或經過了指定時間為止。 Console.WriteLine("newThread State:{0}", th.ThreadState); th.Abort();//在調用此方法的線程上引發 ThreadAbortException,以開始終止此線程的過程。 調用此方法通常會終止線程。 Console.WriteLine("newThread State:{0}", th.ThreadState); } static void newThread() { Console.WriteLine("newThread Start!"); Thread.Sleep(10000); Console.WriteLine("newThread Complete!"); } } }
運行結果

