多線程基礎知識(二)
線程池
- 因為每次創建線程、銷毀線程都比較消耗 cpu 資源,因此可以通過線程池進行優化。線程池是一組已經創建好的線程,隨用隨取,用完了不是銷毀線程,然後放到線程池中,供其他人用。
- 用線程池之後就無法對線程進行精細化的控制了(線程啟停、優先級控制等)。
- ThreadPool 類的一個重要方法:
- static bool QueueUserWorkItem(WaitCallback callBack)
- static bool QueueUserWorkItem(WaitCallback callBack, object state)//用來傳遞一個參數給線程代碼的
- 除非要對線程進行精細化的控制,否則建議使用線程池,因為又簡單、性能調優又更好。
1 static void Main(string[] args) 2 { 3 ThreadPool.QueueUserWorkItem(state => 4 { 5 for (int i = 0; i < 50; i++) 6 { 7 Console.WriteLine(i); 8 } 9 }); 10 }View Code
1 static void Main(string[] args) 2 { 3 4 for (int i = 0; i < 50; i++) 5 { 6 //通過第二個參數給線程傳值 7 ThreadPool.QueueUserWorkItem(state => 8 { 9 Console.WriteLine(state); 10 }, i);View Code11 } 12 Console.Read(); 13 }
三種異步編程模型
.Net 中很多的類接口設計的時候都考慮了多線程問題,簡化了多線程程序的開發。不用自己去寫 WaitHandler 等這些底層的代碼。由於歷史的發展,這些類的接口設計有著三種不同的風格:EAP(*)、APM(*)和 TPL。
目前重點用 TPL。
1.EAP風格:類似於 Ajax 中的XmlHttpRequest,send 之後並不是處理完成了,而是在 onreadystatechange 事件中再通知處理完成
1 WebClient wc = new WebClient(); 2 wc.DownloadStringCompleted += Wc_DownloadStringCompleted; 3 wc.DownloadStringAsync(new Uri("http://www.baidu.com")); 4 private void Wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) 5 { 6 MessageBox.Show(e.Result); 7 }View Code
優點是簡單,缺點是當實現復雜的業務的時候很麻煩;EAP 的類的特點是:一個異步方法配一個***Completed 事件。.Net 中基於 EAP 的類比較少
2.APM風格:是.Net 舊版本中廣泛使用的異步編程模型。使用了 APM的異步方法會返回一個 IAsyncResult 對象,這個對象有一個重要的屬性 AsyncWaitHandle,他是一個用來等待異步任務執行結束的一個同步信號。
APM 的特點是:方法名字以 BeginXXX 開頭,返回類型為 IAsyncResult,調用結束後需要EndXXX。.Net 中有如下的常用類支持 APM:Stream、SqlCommand、Socket 等。
TPL風格:是.Net4.0後帶來的新特性,更簡潔、方便、現在.NET平臺已經大面積使用
註意方法中如果有 await,則方法必須標記為 async,不是所有方法都可以被輕松的標記為 async。
WinForm 中的事件處理方法都可以標記為 async、MVC 中的 Action 方法也可以標記為 async、
控制臺的 Main 方法不能標記為 async。
TPL 的特點:方法都以 XXXAsync 結尾,返回值類型是泛型的 Task<T>。TPL 讓我們可以用線性的方式去編寫異步程序,不再需要像 EAP 中那樣搞一堆回調、邏輯跳來跳去了。
註意TPL中返回值直接使用即可,盡量不要使用其它一些方法的解析,比如:Result()
編寫自己的一個異步方法
以async結尾最好,編寫習慣
static Task<string> F2Async(){ return Task.Run(()=>{ System.Thread.Sleep(2000) return "helloWord!"; }); }
多線程基礎知識(二)