<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    c#異步編程-線程

    共 4998字,需瀏覽 10分鐘

     ·

    2020-10-30 15:00

    c#異步編程-線程

    近期會分享自己學(xué)習(xí)c#異步編程系列的文章,如果能幫助大家希望多多關(guān)注文章末尾的微信公眾號和知乎三連。各位舉手之勞是對我更新技術(shù)文章最大的支持。

    1.線程

    • 線程是一個(gè)可執(zhí)行的路徑,它可以獨(dú)立于其他線程執(zhí)行。

    • 每個(gè)線程都在操作系統(tǒng)的進(jìn)程內(nèi)執(zhí)行,而操作系統(tǒng)進(jìn)程提供了程序運(yùn)行的獨(dú)立環(huán)境。

    • 單線程應(yīng)用,在進(jìn)程的獨(dú)立環(huán)境里跑一個(gè)線程,所以該線程擁有獨(dú)占權(quán)。

    • 多線程應(yīng)用,單個(gè)進(jìn)程中會跑多個(gè)線程,他們會共享當(dāng)前的執(zhí)行環(huán)境(內(nèi)存)等。

    • 進(jìn)程和線程的對應(yīng)關(guān)系,一個(gè)進(jìn)程可以擁有多個(gè)線程,多個(gè)線程只能屬于一個(gè)進(jìn)程。例如:一個(gè)非常耗時(shí)的操作(讀數(shù)據(jù)庫、復(fù)雜耗時(shí)的計(jì)算),如果只用主線程執(zhí)行UI線程會“假死”專業(yè)術(shù)語叫線程阻塞。這時(shí)候的解決辦法就是單獨(dú)開一個(gè)線程去執(zhí)行這個(gè)耗時(shí)操作。這個(gè)時(shí)候處理的數(shù)據(jù)就可被稱作是共享狀態(tài)。

    示例代碼如下:

        static void Main(string[] args)
    {
    Thread t = new Thread(PrintValue);
    t.Start();

    for (int i = 0; i < 1000; i++)
    {
    Console.WriteLine("main thread.");
    }
    }

    static void PrintValue()
    {
    for (int i = 0; i < 1000; i++)
    {
    Console.WriteLine("thread t.");
    }
    }

    效果:

    • 在單核計(jì)算機(jī)上,操作系統(tǒng)必須為每個(gè)線程分派“時(shí)間片”(在windows中通常為20毫秒)來模擬并發(fā),從而導(dǎo)致重復(fù)的"main thread."和"thread t."輸出。

    • 在多核或多處理計(jì)算機(jī)上,這兩個(gè)線程可以真正的并行執(zhí)行(也可能受到計(jì)算機(jī)上其他活動進(jìn)程的競爭)。

    • 線程搶占:A線程的執(zhí)行與另外一個(gè)線程上代碼的執(zhí)行交織的那一刻。可被成為線程搶占。

    線程屬性:

    • 線程一旦開始執(zhí)行,isAlive就是True,線程結(jié)束就編程false。

    • 線程結(jié)束的條件就是:線程構(gòu)造函數(shù)傳入的委托結(jié)束了執(zhí)行。

    • 線程一旦結(jié)束,就無法再重啟,因?yàn)榫€程需要執(zhí)行的代碼執(zhí)行完成之后會自動銷毀。

    • 每個(gè)線程都有Name屬性,通常用于調(diào)試。每個(gè)線程的Name只能設(shè)置一次,以后更改會拋出異常。

    • 靜態(tài)的Thread.CurrentThread屬性,會返回當(dāng)前執(zhí)行的線程。



    static void Main(string[] args)
    {
    Thread.CurrentThread.Name = "Main_Thread";
    Thread t = new Thread(PrintValue);
    t.Name = "T_Thread";
    t.Start();

    Console.WriteLine(Thread.CurrentThread.Name);

    for (int i = 0; i < 1000; i++)
    {
    Console.WriteLine("main thread.");
    }
    }

    static void PrintValue()
    {
    for (int i = 0; i < 1000; i++)
    {
    Console.WriteLine("thread t.");
    }
    }

    2.Thread.Join 和 Thread.Sleep

    Join();

    • 調(diào)用Join方法,就可以等待另一個(gè)線程結(jié)束。也叫阻塞線程

    示例代碼如下:

        static void Main(string[] args)
    {
    #region Join and Sleep

    Thread t = new Thread(PrintValue);
    t.Start();
    t.Join();//等待PrintValue執(zhí)行完成
    Console.WriteLine("End.");

    #endregion
    }

    static void PrintValue()
    {
    for (int i = 0; i < 1000; i++)
    {
    Console.WriteLine("thread t.");
    }
    }
    • 調(diào)用join的時(shí)候,可以設(shè)置一個(gè)超時(shí),用毫秒或者TimeSpan都可以。

    • 如果返回true,那就是線程結(jié)束;如果超時(shí),則返回false。


        static Thread t1, t2;

    static void Main(string[] args)
    {
    t1 = new Thread(ThreadTest);
    t1.Name = "t1";
    t1.Start();
    t2 = new Thread(ThreadTest);
    t2.Name = "t2";
    t2.Start();
    }

    private static void ThreadTest()
    {
    Console.WriteLine("Current thread:{0}",Thread.CurrentThread.Name);

    if (Thread.CurrentThread.Name == "t1" && t2.ThreadState != ThreadState.Unstarted)
    {
    if (t2.Join(1000))
    {
    Console.WriteLine("t2 join 2000ms.");
    }
    else
    {
    Console.WriteLine("the time out.");
    }
    }

    Thread.Sleep(4000);
    Console.WriteLine("thread 1:{0}", t1.ThreadState);
    Console.WriteLine("thread 2:{0}", t2.ThreadState);
    }

    效果:

    Sleep()

    • Thread.Sleep()方法會暫停當(dāng)前的線程,并等一段時(shí)間。期間是不占用cpu資源的。

      for (int i = 0; i < 3; i++)
      {
      for (int j = 0; j < 10000; j++)
      {
      Console.WriteLine("i");
      }
      Thread.Sleep(4000);
      }

      驗(yàn)證:在每次i循環(huán)的時(shí)候會占用CPU輸出10000次,然后休息4秒再繼續(xù)循環(huán)。這時(shí)候分析圖如下:


    3.前臺線程和后臺線程

    前臺線程:

    • 該線程在沒有執(zhí)行完成函數(shù)代碼時(shí),在程序關(guān)閉時(shí)是不會退出進(jìn)程的。


        Thread t1 = new Thread(PrintValue);
    t1.IsBackground = true;
    t1.Start();

    static void PrintValue()
    {
    while (true)
    {
    Console.WriteLine("thread t.");
    }
    }

    效果:

    后臺線程:

    • 該線程不管有沒有執(zhí)行完成函數(shù)代碼,都會直接退出進(jìn)程。


        Thread t1 = new Thread(PrintValue);
    t1.IsBackground = false;
    t1.Start();

    static void PrintValue()
    {
    while (true)
    {
    Console.WriteLine("thread t.");
    }
    }

    4.線程優(yōu)先級

    線程優(yōu)先級決定了相對于操作系統(tǒng)中其他活躍線程所占的執(zhí)行時(shí)間,提升指定線程優(yōu)先級如果該線程處理任務(wù)比較重則會降低其他線程優(yōu)先級會導(dǎo)致其他搶占不到CPU處理時(shí)間片,。

    Thread t1 = new Thread(() => { Console.ReadLine(); });
    t1.Priority = ThreadPriority.Highest;
    t1.Start();

    ThreadPriority枚舉如下:

    //
    // 摘要:
    // Specifies the scheduling priority of a System.Threading.Thread.
    public enum ThreadPriority
    {
    //
    // 摘要:
    // The System.Threading.Thread can be scheduled after threads with any other priority.
    Lowest = 0,
    //
    // 摘要:
    // The System.Threading.Thread can be scheduled after threads with Normal priority
    // and before those with Lowest priority.
    BelowNormal = 1,
    //
    // 摘要:
    // The System.Threading.Thread can be scheduled after threads with AboveNormal priority
    // and before those with BelowNormal priority. Threads have Normal priority by default.
    Normal = 2,
    //
    // 摘要:
    // The System.Threading.Thread can be scheduled after threads with Highest priority
    // and before those with Normal priority.
    AboveNormal = 3,
    //
    // 摘要:
    // The System.Threading.Thread can be scheduled before threads with any other priority.
    Highest = 4
    }

    如果想讓某線程的優(yōu)先級比其他進(jìn)程中的線程高,那么就必須提升進(jìn)程的優(yōu)先級。

    • 使用system.Diagnostics下的Process類。

      using(Process p = Process.GetCurrentProcess()) p.PriorityClass = ProcessPriorityClass.High;

    • 這可以很好的用于只做少量工作且需要較低延遲的非UI進(jìn)程。

    • 對于需要大量計(jì)算的程序(wpf、winfrom等),提高進(jìn)程優(yōu)先級可能會降低其他進(jìn)程搶占不到CPU處理時(shí)間片,從而降低整個(gè)計(jì)算機(jī)的速度。


    瀏覽 45
    點(diǎn)贊
    評論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)
    評論
    圖片
    表情
    推薦
    點(diǎn)贊
    評論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    国产被操| 成人看片黄a免费看视频 | 天天操天天干天天爽 | 精品人妻无码一区二区三区竹菊影视 | 婷婷五月天丁香激情 |