C#線程簡介

語言: CN / TW / HK

theme: cyanosis highlight: a11y-dark


這是我參與「掘金日新計劃 · 8 月更文挑戰」的第5天,點擊查看活動詳情


線程:

對於所有需要等待的操作,例如移動文件,數據庫和網絡訪問都需要一定的時間,此時就可以啟動一個新的線程,同時完成其他任務。一個進程的多個線程可以同時運行在不同的CPU上或多核CPU的不同內核上。 線程是程序中獨立的指令流。在VS編輯器中輸入代碼的時候,系統會分析代碼,用下劃線標註遺漏的分號和其他語法錯誤,這就是用一個後台線程完成。Word文檔需要一個線程等待用户輸入,另一個線程進行後台搜索,第三個線程將寫入的數據存儲在臨時文件中。運行在服務器上的應用程序中等待客户請求的線程成為偵聽器線程。 進程包含資源,如Window句柄,文件系統句柄或其他內核對象。每個進程都分配的虛擬內存。一個進程至少包含一個線程。 一個應用程序啟動,一般會啟動一個進程,然後進程啟動多個線程。


線程的優先級:

線程有操作系統調度,一個CPU同一時間只能做一件事情(運行一個線程中的計算任務),當有很多線程需要CPU去執行的時候,線程調度器會根據線程的優先級去判斷先去執行哪一個線程,如果優先級相同的話,就使用一個循環調度規則,逐個執行每個線程。 在Thead類中,可以設置Priority屬性,以影響線程的基本優先級 ,Priority屬性是一個ThreadPriority枚舉定義的一個值。定義的級別有Highest ,AboveNormal,BelowNormal 和 Lowest。


控制線程

  1. 獲取線程的狀態(Running還是Unstarted,,,),當我們通過調用Thread對象的Start方法,可以創建線程,但是調用了Start方法之後,新線程不是馬上進入Running狀態,而是出於Unstarted狀態,只有當操作系統的線程調度器選擇了要運行的線程,這個線程的狀態才會修改為Running狀態。我們使用Thread.Sleep()方法可以讓當前線程休眠進入WaitSleepJoin狀態。
  2. 使用Thread對象的Abort()方法可以停止線程。調用這個方法,會在終止要終止的線程中拋出一個ThreadAbortException類型的異常,我們可以try catch這個異常,然後在線程結束前做一些清理的工作。
  3. 如果需要等待線程的結束,可以調用Thread對象的Join方法,表示把Thread加入進來,停止當前線程,並把它設置為WaitSleepJoin狀態,直到加入的線程完成為止。

線程池(默認為後台線程)

創建線程需要時間。 如果有不同的小任務要完成,就可以事先創建許多線程 , 在應完成這些任務時發出請求。 這個線程數最好在需要更多的線程時增加,在需要釋放資源時減少。

不需要 自己創建線程池,系統已經有一個ThreadPool類管理線程。 這個類會在需要時增減池中線程的線程數,直到達到最大的線程數。 池中的最大線程數是可配置的。 在雙核 CPU中 ,默認設置為1023個工作線程和 1000個 I/o線程。也可以指定在創建線程池時應立即啟動的最小線程數,以及線程池中可用的最大線程數。 如果有更多的作業要處理,線程池中線程的個數也到了極限,最新的作業就要排隊,且必須等待線程完成其任務。

``` namespace 線程池創建線程 { class Program { static void Main(string[] args) { ThreadPool.QueueUserWorkItem(SmallThread); ThreadPool.QueueUserWorkItem(SmallThread); ThreadPool.QueueUserWorkItem(SmallThread); ThreadPool.QueueUserWorkItem(SmallThread); ThreadPool.QueueUserWorkItem(SmallThread); ThreadPool.QueueUserWorkItem(SmallThread); ThreadPool.QueueUserWorkItem(SmallThread);

        Console.Read();
    }
    static void SmallThread(object filename)
    {
        Console.WriteLine("線程開始,ID:"+Thread.CurrentThread.ManagedThreadId);
        Thread.Sleep(1000);
        Console.WriteLine("線程結束");
    }
}

} ```

使用線程池需要注意的事項:

線程池中的所有線程都是後台線程 。 如果進程的所有前台線程都結束了,所有的後台線程就會停止。 不能把入池的線程改為前台線程 。 不能給入池的線程設置優先級或名稱。 入池的線程只能用於時間較短的任務。 如果線程要一直運行(如 Word的拼寫檢查器線程),就應使用Thread類創建一個線程。