C# 多線程學習筆記 - 1
阿新 • • 發佈:2019-01-31
agg 部分 console csharp 回調方法 提高 作者 lse 超時
本文主要針對 GKarch 相關文章留作筆記,僅在原文基礎上記錄了自己的理解與摘抄部分片段。
遵循原作者的 CC 3.0 協議。
如果想要了解更加詳細的文章信息內容,請訪問下列地址進行學習。原文章地址:https://blog.gkarch.com/threading/part2.html
基礎知識
- 靜態字段是在所有線程當中共享狀態的。
- 一個線程被阻塞時,不會消耗 CPU 資源。
- Join 可以等待另一個線程結束,Sleep 可以將線程阻塞指定的時間,兩者使用時線程都是阻塞狀態。
- Join 可以設置超時時間,當線程執行超過指定時間返回 False。
Thread.Sleep(0)
會釋放當前時間片,將 CPU 資源讓出給其他線程。Thread.Sleep(0)
作用與Thread.Yield()
作用一樣,後者只會讓出給當前核心的其他線程。Thread.Yield()
執行時會影響到程序的話,基本可以確定代碼存在 Bug。- 在使用 Lambda 表達式啟動線程並傳入變量的時候,不要在啟動線程之後更改被捕獲變量的值。
- 線程分為前臺線程與後臺線程,當所有前臺線程中止時,程序自動退出。
- 可以顯式地提高線程優先級,但可能會導致線程饑餓。
線程池
由於線程創建成本高昂(私有局部變量棧,每個線程默認占用 1 MB內存),所以一般都會使用線程池來進行線程的創建與回收。
線程池線程可以臨時更改其優先級,在回收後會恢復默認狀態。
開發人員可以通過
Thread.CurrentThread.IsThreadPoolThread
屬性查詢線程是否運行在線程池中。通過查詢 Task.Result 會導致當前線程阻塞,直到任務執行完成,如果發生錯誤,則會將異常包裝到
AggregateException
異常內進行拋出。通過異步委托可以快速創建一個工作線程。
- 創建目標方法委托。
- 在委托上調用
BeginInvoke()
方法,保存其IActionResult
返回值。 - 需要返回結果時,調用
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 平臺上是無法運行的。
異步委托在調用
BeginInvoke()
的時候可以傳入回調方法。線程池可以通過
ThreadPool.SetMaxThreads
與ThreadPool.SetMinThreads
進行優化。
C# 多線程學習筆記 - 1