C#執行緒篇---解答執行緒之惑(2)
我們都知道,在這個行業,追求的就是用最少的時間學最多的知識,這是我寫這個系列最想達到的目標,在最快的時間內,幫助更多的人學習更多的執行緒知識。
前一篇,講述了執行緒基礎,給大家鋪墊了一個基礎,這一篇著重介紹執行緒的作用及其工作方式,順便小試牛刀一把。
現在我想提出,最直接的問題是:
為什麼要使用執行緒?
為什麼要使用執行緒?答案只有三點(歡迎補充^_^):
- 使用執行緒可以將程式碼同其他程式碼隔離。這將提高應用程式的可靠性,這不僅僅是應用程式所需要的,更是Windows引入執行緒的真正原因。
- 使用執行緒可以簡化程式設計。
- 可以用執行緒來程式的實現併發執行,雙管齊下,效率,你懂的(∩_∩)。
說了這麼些,總得試試手啊,使用執行緒?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的執行緒池可以更安全的完成這些事,如果你一定要創
建自己的執行緒,開始執行專用執行緒時,需考慮以下四點內容:
- 執行緒需要以非普通執行緒優先執行。執行緒池執行緒都是普通優先順序執行,可以更改這個優先順序,但不建議這麼做。在不同的執行緒池操縱之間,優先順序的更改是無法延續的(執行緒池這個概念下篇解析)。
- 需要執行緒表現為一個前臺程序,防止應用程式線上程結束它的任務之前終止。(執行緒池的執行緒始終是後臺執行緒,如果CLR要終止程序,它們就可能無法被迫完成任務)
- 一個計算限制的任務需要長時間的執行,就像例子中StartCode(),它執行的就是計算限制的任務。為長時間執行的任務建立一個專業執行緒,用於避免這個問題。
- 任務執行緒可能呼叫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-~~