C# 多執行緒學習筆記 – 1

myzony發表於2019-01-31

本文主要針對 GKarch 相關文章留作筆記,僅在原文基礎上記錄了自己的理解與摘抄部分片段。
遵循原作者的 CC 3.0 協議
如果想要了解更加詳細的文章資訊內容,請訪問下列地址進行學習。

原文章地址:https://blog.gkarch.com/threading/part1.html

基礎知識

  1. 靜態欄位是在所有執行緒當中共享狀態的。
  2. 一個執行緒被阻塞時,不會消耗 CPU 資源。
  3. Join 可以等待另一個執行緒結束,Sleep 可以將執行緒阻塞指定的時間,兩者使用時執行緒都是阻塞狀態。
  4. Join 可以設定超時時間,當執行緒執行超過指定時間返回 False。
  5. Thread.Sleep(0) 會釋放當前時間片,將 CPU 資源讓出給其他執行緒。
  6. Thread.Sleep(0) 作用與 Thread.Yield() 作用一樣,後者只會讓出給當前核心的其他執行緒。
  7. Thread.Yield() 執行時會影響到程式的話,基本可以確定程式碼存在 Bug。
  8. 在使用 Lambda 表示式啟動執行緒並傳入變數的時候,不要在啟動執行緒之後更改被捕獲變數的值。
  9. 執行緒分為前臺執行緒與後臺執行緒,當所有前臺執行緒中止時,程式自動退出。
  10. 可以顯式地提高執行緒優先順序,但可能會導致執行緒飢餓。

執行緒池

  1. 由於執行緒建立成本高昂(私有區域性變數棧,每個執行緒預設佔用 1 MB記憶體),所以一般都會使用執行緒池來進行執行緒的建立與回收。

  2. 執行緒池執行緒可以臨時更改其優先順序,在回收後會恢復預設狀態。

  3. 開發人員可以通過 Thread.CurrentThread.IsThreadPoolThread 屬性查詢執行緒是否執行線上程池中。

  4. 通過查詢 Task.Result 會導致當前執行緒阻塞,直到任務執行完成,如果發生錯誤,則會將異常包裝到 AggregateException 異常內進行丟擲。

  5. 通過非同步委託可以快速建立一個工作執行緒。

    1. 建立目標方法委託。
    2. 在委託上呼叫 BeginInvoke() 方法,儲存其 IActionResult 返回值。
    3. 需要返回結果時,呼叫 EndInvoke() 方法,傳遞儲存的 IActionResult 物件。
    class Program
    {
     static void Main(string[] args)
     {
         Func<string, int> work = Work;
    
         var result = work.("測試",null,null);
    
         Console.WriteLine("獲得結果");
    
         work.EndInvoke(result);
     }
    
     public static int Work(string inputStr)
     {
         Console.Write(Thread.CurrentThread);
         return inputStr.Length;
     }
    }

    注意:

      上述程式碼在 .NET Core 平臺上是無法執行的。

  6. 非同步委託在呼叫 BeginInvoke() 的時候可以傳入回撥方法。

  7. 執行緒池可以通過 ThreadPool.SetMaxThreadsThreadPool.SetMinThreads 進行優化。

相關文章