1. 程式人生 > >C#執行緒篇---解答執行緒之惑(2)

C#執行緒篇---解答執行緒之惑(2)

我們都知道,在這個行業,追求的就是用最少的時間學最多的知識,這是我寫這個系列最想達到的目標,在最快的時間內,幫助更多的人學習更多的執行緒知識。

    前一篇,講述了執行緒基礎,給大家鋪墊了一個基礎,這一篇著重介紹執行緒的作用及其工作方式,順便小試牛刀一把。

    現在我想提出,最直接的問題是:

    為什麼要使用執行緒?

  為什麼要使用執行緒?答案只有三點(歡迎補充^_^):

  1. 使用執行緒可以將程式碼同其他程式碼隔離。這將提高應用程式的可靠性,這不僅僅是應用程式所需要的,更是Windows引入執行緒的真正原因。
  2. 使用執行緒可以簡化程式設計。
    這個答案有利有弊,需要從兩方面考慮:第一點:使用執行緒的同時也就意味著會付出一些資源作為代價,對於現在的計算機,付出資源是值得的,因為它的資源根本沒有發掘出來。第二點:引用執行緒的時候是在需要相互協作的程式碼時,不能隨便的引用執行緒,盲目的使用執行緒,只會增加程式碼複雜度。
  3. 可以用執行緒來程式的實現併發執行,雙管齊下,效率,你懂的(∩_∩)。

說了這麼些,總得試試手啊,使用執行緒?so easy:

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             Console.WriteLine("主執行緒:啟動專用執行緒...");
 6             Thread dedicatedThread = new Thread(StartCode);
 7 
 8             dedicatedThread.Start(5);
 9 
10            
11             Console.WriteLine("主執行緒:執行到此");
12             Thread.Sleep(10000);//模擬主執行緒操作
13             dedicatedThread.Join();
14             Console.WriteLine("主執行緒:執行完畢");
15         }
16 
17         private static void StartCode(Object obj)
18         {
19             Console.WriteLine("子執行緒:啟動程式碼!{0}",obj);
20             Thread.Sleep(1000);//模擬程式碼操作
21            
22         }
23     }

下面是我兩次執行的結果:

  

這是最基本的執行緒運用,好像不難哦?但是不提倡這麼用。

中間有個Join方法,Join的作用是:造成呼叫執行緒阻塞當前執行的任何程式碼,直到dedicatedThread所代表的執行緒終止或銷燬。

同一個程式出現兩種輸出結果,這是為什麼?程式的每次輸出不該是一樣的嗎?

兩種輸出的不一樣是因為Windows對兩個執行緒進行排程的方式不同,這無法控制。Windows搶佔式多執行緒這一概念覺得了這因素。

這個知識點大家有必要了解,這個例子是個專用執行緒你可以這麼用,但是建議應避免這麼做,CLR的執行緒池可以更安全的完成這些事,如果你一定要創

建自己的執行緒,開始執行專用執行緒時,需考慮以下四點內容:

  1. 執行緒需要以非普通執行緒優先執行。執行緒池執行緒都是普通優先順序執行,可以更改這個優先順序,但不建議這麼做。在不同的執行緒池操縱之間,優先順序的更改是無法延續的(執行緒池這個概念下篇解析)。
  2. 需要執行緒表現為一個前臺程序,防止應用程式線上程結束它的任務之前終止。(執行緒池的執行緒始終是後臺執行緒,如果CLR要終止程序,它們就可能無法被迫完成任務)
  3. 一個計算限制的任務需要長時間的執行,就像例子中StartCode(),它執行的就是計算限制的任務。為長時間執行的任務建立一個專業執行緒,用於避免這個問題。
  4. 任務執行緒可能呼叫Abort()(屬於Thread)來提前終止它。

 執行緒可以分為前臺執行緒和後臺執行緒

  CLR將每個執行緒要麼視為前臺,要麼視為後臺執行緒。當一個程序中的所有前臺執行緒停止執行時(也就是我們按右上角的X,關閉程式),CLR將強制終止仍在執行的後臺執行緒直接終止,不會異常。

  基於這個原因,前臺執行緒的使用應該用於執行確實想完成的任務,就用個我們正在用瀏覽器(下面稱前臺執行緒)做例子:

  你正在瀏覽本篇內容,就意味著這個前臺執行緒,正要完成你所需求的任務指令,解析HTML程式碼,便於你的閱讀,這是首要任務。而載入書籤,讀取收藏網址的資訊等,關鍵的後臺功能,能在應用程式重啟的時候繼續執行,如果關閉前臺執行緒,它們沒必要保持活動的狀態。

下面來看個前臺執行緒和後臺執行緒的程式實現:

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             Thread t = new Thread(StartCode);
 6            // t.IsBackground = true;
 7             t.Start();
 8 
 9             Console.WriteLine("主執行緒執行完畢!");
10         }
11 
12         private static void StartCode()
13         {
14             Console.WriteLine("開始執行子執行緒...");
15             Thread.Sleep(10000);//模擬程式碼操作
16             Console.WriteLine("子執行緒執行完畢!");
17            
18         }
19     }

這段可執行程式碼就是預設模式,執行的前臺程式碼。它的輸出也是你能預測的:

在“開始執行子執行緒...”的時候,需要等待10秒。

去掉第6行的註釋,再看看執行結果:

它不會等待,並看不到“子執行緒執行完畢”這句話。

前臺的好處是,你可以保證你的後臺執行緒能執行完畢,後臺執行緒的好處是,你不用管它的執行。

在一個執行緒的生存期中,任何時候都可以進行前後臺互換。

CLR要提供前臺執行緒和後臺執行緒的概念來更好的支援應用程式域(俗稱AppDoMain),每個AppDoMain都可以執行一個單獨的應用程式,每個應用程式都有它的前臺執行緒,一個應用程式退出,前臺執行緒終止,對應的後臺執行緒也要終止,但CLR執行緒仍然需要執行,使其他應用程式繼續執行,所有應用程式退出後,整個程序就可以銷燬了。CLR算是執行緒執行的一個空間。

  最後,說個大家十分熟悉的功能,用過Visual Studio 的開發人員,我保證你們都體驗過這個功能。

  智慧提示都知道,這個是典型的執行緒運用,很快捷很舒心是不是?

  當你寫程式碼寫到興頭時,發現編譯器畫出紅線提示你,某處程式碼出錯了。有沒有發現這個?怎麼實現的?

  在你停止輸入的時候,編譯器就會開始編譯程式碼,檢測程式碼中的出錯部分,很人性化,這大大提高了C#開發人員的工作效率,而在這,執行緒功不可沒,執行緒的力量可見一斑。

  執行緒基礎還有一節重要的。下回講~~~更新有點慢,是為了寫出更好的部落格。(^。^)y-~~