<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # [C# 線程處理系列]專題一:線程基礎 **引言:** 最近一段時間都在研究關于.Net線程的內容,覺得線程是每個程序員都應該掌握的,所以寫下這個線程的系列希望能給大家學習過程中一些幫助,同時也是自己對線程的鞏固,當中如果有什么錯漏還請大家指出,這樣我們可以互相得到進步。 **目錄**: 一、線程的介紹 二、線程調度和優先級 三、前臺線程和后臺線程 四、簡單線程的使用 **一、線程的介紹** 在介紹線程之前, 很有必要知道什么是進程,以及與線程的關系。 **進程**(Process)是應用程序的實例要使用的**資源**的一個集合(從可以簡化理解:進程就是一種**資源**,是應用程序所用的資源)。每個應用程序都在各自的進程中運行來確保應用程序不受其他應用程序的影響,如果一個應用程序失敗了, 只會影響自己的進程,其他進程中的應用程序可以繼續運行。進程是操作系統為我們提供的一種保護應用程序的一種機制。 **線程**是進程中基本執行單元, 一個進程中可以包含多個線程,在進程入口執行的第一個線程是一個進程的主線程,在.Net應用程序中,都是以Main()方法作為程序的入口的, 所以在程序運行過程中調用這個方法時,系統就會自動創建一個主線程。(他們之間的關系簡單說:線程是進程的執行單元,進程是線程的一個容器了)。 **二、線程調度和優先級** Windows之所以被稱為搶占式多線程操作系統,是因為線程可以在任意時間被搶占,并調度另一個線程。每個線程都分配了從0~31的一個優先級。系統首先把高優先級的線程分配給CPU執行。Windows 支持7個相對線程優先級:Idle,Lowest,Below Normal,Normal,Above Normal,Highest和Time-Critical,Normal是默認的線程優先級,然而在程序中可以通過設置Thread的Priority屬性來改變線程的優先級,它的類型為ThreadPriority枚舉類型,包含枚舉有:Lowest,BelowNormal,Normal,AboveNormal和Highest,CLR為自己保留了 Idle和Time-Critical優先級。具體每個枚舉值含義如下表: | 成員名稱 | 說明 | | --- | --- | | Lowest | Thread can be scheduled after threads with any other priority." data-guid="3e53547e0e9a509aff4a76382e494083"&gt;可以將 Thread何其他優先級的線程之后。 | | BelowNormal | Thread can be scheduled after threads with Normal priority and before those with Lowest priority." data-guid="f979b4a5dfbb5a35942312092b2cd47a"&gt;可以將 Thread Normal 優先級的線程之后,在具有 Lowest 優先級的線程之前。 | | Normal | Thread can be scheduled after threads with AboveNormal priority and before those with BelowNormal priority." data-guid="8b94d9644aacd17640f4971fc6e79dc7"&gt;可以將 Thread AboveNormal 優先級的線程之后,在具有 BelowNormal 優先級的線程之前。 Normal priority by default." data-guid="6fa67ded483ad3d242ea365f0ac225c4"&gt;默認情況下,線程具有 Normal 優先級。 | | AboveNormal | Thread can be scheduled after threads with Highest priority and before those with Normal priority." data-guid="d067edb8ea0b5bfd51a2591334b86fd7"&gt;可以將 Thread Highest 優先級的線程之后,在具有 Normal 優先級的線程之前。 | | Highest | Thread can be scheduled before threads with any other priority." data-guid="fc7a0e931c772d08fc98b6de2c82ab3c"&gt;可以將 Thread 其他優先級的線程之前。 | **三、前臺線程和后臺線程** 在.net中線程分為前臺線程和后臺線程,在一個進程中,當所有前臺線程停止運行時,CLR會強制結束仍在運行的任何后臺線程,這些后臺線程直接被終止,不會拋出異常。 所以我們應該在前臺線程中執行我們確實要完成的事情,另外, 應該把非關鍵的任務使用后臺線程,我們用Thread創建的是線程為前臺線程。讓我們通過下面的一段代碼來看看前臺線程和后臺線成的區別: ``` using System; using System.Threading; class Program { static void Main(string[] args) { // 創建一個新線程(默認為前臺線程) Thread backthread = new Thread(Worker); // 使線程成為一個后臺線程 backthread.IsBackground = true; // 通過Start方法啟動線程 backthread.Start(); // 如果backthread是前臺線程,則應用程序大約5秒后才終止 // 如果backthread是后臺線程,則應用程序立即終止 Console.WriteLine("Return from Main Thread"); } private static void Worker() { // 模擬做10秒 Thread.Sleep(5000); // 下面語句,只有由一個前臺線程執行時,才會顯示出來 Console.WriteLine("Return from Worker Thread"); } } ``` 運行上面代碼可以發現:控制臺中顯示字符串: Return form Main Thread 后就退出了, 字符串 Return from Worker Thread字符串根本就沒有顯示,這是因為此時的backthread線程為后臺線程,當主線程(執行Main方法的線程,主線程當然也是前臺線程了)結束運行后,CLR會強制終止后臺線程的運行,整個進程就被銷毀了,并不會等待后臺線程運行完后才銷毀。如果把 backthread.IsBackground = true; 注釋掉后, 就可以看到控制臺過5秒后就輸出 Return from Worker Thread。再在Worker方法最后加一句 代碼:Console.Read(); 就可以看到這樣的結果了: ![](https://box.kancloud.cn/2016-01-23_56a2eb31a54bd.png) **注意**:有些人可能會問我不想把 backthread.IsBackground = true;注釋掉, 又想把Worker()方法中的字符串輸出在控制臺上怎么做呢? 其實是有解決的辦法的, 我們可以調用thread.Join()方法來實現,Join()方法能保證主線程(前臺線程)在異步線程thread(后臺線程)運行結束后才會運行。 實現代碼如下: ``` using System; using System.Threading; class Program { static void Main(string[] args) { // 創建一個新線程(默認為前臺線程) Thread backthread = new Thread(Worker); // 使線程成為一個后臺線程 backthread.IsBackground = true; // 通過Start方法啟動線程 backthread.Start(); backthread.Join(); // 模擬主線程的輸出 Thread.Sleep(2000); Console.WriteLine("Return from Main Thread"); Console.Read(); } private static void Worker() { // 模擬做3秒 Thread.Sleep(3000); // 下面語句,只有由一個前臺線程執行時,才會顯示出來 Console.WriteLine("Return from Worker Thread"); } } ``` 運行結果(調用Join方法后后臺線程會阻塞主線程所以主線程會后輸出): ![](https://box.kancloud.cn/2016-01-23_56a2eb31b4881.jpg) **四、簡單線程的使用** 其實在上面介紹前臺線程和后臺線程的時候已經通過ThreadStart委托創建了一個線程了,此時已經實現了一個多線程的一個過程,為此系列中將多線程也是做一個鋪墊吧。下面通過**ParameterizedThreadStart**委托的方式來實現多線程。 以**ParameterizedThreadStart**委托的方式來實現多線程: ``` using System; using System.Threading; class Program { static void Main(string[] args) { // 創建一個新線程(默認為前臺線程) Thread backthread = new Thread(new ParameterizedThreadStart(Worker)); // 通過Start方法啟動線程 backthread.Start("123"); // 如果backthread是前臺線程,則應用程序大約5秒后才終止 // 如果backthread是后臺線程,則應用程序立即終止 Console.WriteLine("Return from Main Thread"); } private static void Worker(object data) { // 模擬做5秒 Thread.Sleep(5000); // 下面語句,只有由一個前臺線程執行時,才會顯示出來 Console.WriteLine(data + " Return from Worker Thread"); Console.Read(); } } ``` 注意:此時Worker方法傳入了一個參數,并且Start方法也傳遞了一個字符傳參數。 對比與之前創建Thread的不同, 運行結果為: ![](https://box.kancloud.cn/2016-01-23_56a2eb31c5f66.png) 寫到這里, 本系列的第一篇差不多講完了,在后續的文章將會介紹Thread方法的使用以及通過一些例子來展示他們的不同之處(像Abort()方法Interrupt方法等)對于線程的一些高級使用(如線程池,并行編程和PLINQ、線程同步和計時器)都會在后續中講到。希望本系列可以給初學線程的人有所幫助。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看