提示:本文所提到的線程狀態變化,並不是指線程啟動、暫停、停止,而是說線程內部狀態的遷移。
隨着軟件技術不斷發展,用戶需求不斷提升,多線程的重要性日益凸顯。
關於線程,通俗的講,每當啟動一個exe應用程序,都會創建一個進程和一個主線程,主線程用來處理界面繪制、界面事件響應等工作,而進程則是線程的容器,主線程和用戶創建的新線程,都將在相應的進程中維護。
由此可知,一個程序之所以能工作,是線程的功勞,進程僅僅是容器而已,一旦程序的主線程被阻塞,就會造成界面無響應等現象,這時候就要用多線程解決問題。
然而,在程序中使用多線程,是比較頭疼的一件事。以我的體會,多線程首先會造成程序不穩定,處理不好容易導致程序崩潰。其次,多線程控制並不是那么容易,比如線程狀態監控、線程訪問沖突等等。最后,還有一個線程通信問題,線程和線程之間的數據交互、消息通知等,並不是那么容易,往往涉及高級知識,比如委托。
很多情況下,我們希望能獲得線程的“返回值”,也就是能夠獲得線程中的數據,當線程內部狀態發生改變時,我們能及時獲取關鍵數據,來進行不同的處理。
遺憾的是,線程是沒有返回值的,在線程中運行的方法,返回值必須是void,但可以有參數。
本文就從這個角度出發,通過一個簡單的小技巧,及時捕獲線程狀態變化,並且獲得關鍵數據。
思路如下圖:
簡單的解釋一下,核心思想:通過定義接口,來規范線程參數,當線程內部狀態遷移時,調用接口中定義的對應處理方法,達到捕獲線程狀態的目的,同時也能獲得線程內部關鍵數據。
代碼實現如下:
winform窗體中的代碼(對應線程相關類):
1 using System.Threading; 2 3 /// <summary> 4 /// 響應開始按鈕單擊事件 5 /// </summary> 6 /// <param name="sender"></param> 7 /// <param name="e"></param> 8 private void btnStart_Click(object sender, EventArgs e) 9 { 10 //實例化ThreadNotice類對象,ThreadNotice類實現了IThreadNotice接口 11 IThreadNotice tn = new ThreadNotice(); 12 //實例化一個Thread對象,並且指定該Thread對象執行Run方法 13 Thread th = new Thread(Run); 14 //啟動線程,並且傳入線程方法(Run)需要的一個參數 15 //注意,這里最多能傳入一個參數!!並且要求線程方法的參數為Object類型!! 16 th.Start(tn); 17 } 18 19 //線程中運行的方法 20 void Run(Object obj) 21 { 22 //將對象轉換成接口類型 23 IThreadNotice tn = (IThreadNotice)obj; 24 //假設狀態為1,則調用實現IThreadNotice接口類的狀態1處理方法,並傳入狀態1下的數據 25 tn.ThreadEvent1("狀態1"); 26 //假設為狀態2,則調用實現IThreadNotice接口類的狀態2處理方法,並傳入狀態2下的數據 27 tn.ThreadEvent2("狀態2"); 28 }
線程狀態處理接口:
1 //線程狀態通知接口 2 public interface IThreadNotice 3 { 4 //狀態1處理方法 5 void ThreadEvent1(string msg); 6 //狀態2處理方法 7 void ThreadEvent2(string msg); 8 }
狀態處理類:
1 using System.Diagnostics; 2 3 //ThreadNotice類實現了IThreadNotice接口 4 public class ThreadNotice:IThreadNotice 5 { 6 //ThreadNotice類對於狀態1的處理 7 public void ThreadEvent1(string msg) 8 { 9 Debug.WriteLine("ThreadNotice類處理——" + msg); 10 } 11 12 //ThreadNotice類對於狀態2的處理 13 public void ThreadEvent2(string msg) 14 { 15 Debug.WriteLine("ThreadNotice類處理——" + msg); 16 } 17 }
效果圖:
相信讀者已經看出,此方法只能達到捕獲、處理線程狀態的效果,並不能把線程中的數據返回。也就是說,雖然我們捕獲了線程狀態,獲取了關鍵數據,但這仍然是一種向下的深層調用,並沒有向上層返回。比如,做不到把線程中的數據顯示在界面上,那將用到委托技術。
此文僅僅是個人實際使用心得,合理性、實用性等均有待考證,僅供參考!