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-~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM