[C#.NET][TPL] 初探 TPL 用法
在.NET 4.0 版本的執行緒處理中,微軟增加了平行運算函式庫 Task Parallel Library (TPL),主要是增加 System.Threading.Tasks 命名空間中的API,請參考
http://msdn.microsoft.com/zh-tw/library/dd460717%28v=vs.100%29.aspx
不過,要使用平行運算前,要先理解自己要開發的工作流程是屬於串行流程還是平行流程,若工作流程是屬於串行流程,在這種情況下使用平行運算很有可能會讓程式運行速度變慢;當然,也不是所有的流程使用執行緒處理後一定會變快,一定要瞭解自己的工作流程。
下圖,表示串行流程,區塊內的工作必須有順序性的,在這情況下 TPL 幫不了太大的忙
如下圖,區塊內的工作,跟其他區塊沒有關係,用 TPL 可感覺明顯的優化。
Task / Task.Factory 會將多個工作分派到每一個CPU。
Parallel.For /Parallel.ForEach 會將單一工作切成好幾塊,並分派到每一個CPU。
比如:發送簡訊給通訊錄裡的手機,發送機制沒有卡到其他流程
串行運算:
如下列程式碼,迴圈內的工作,沒有順序關係也不需要等待彼此。
for (int i = 0; i < contact.Peoples.Count; i++) { SMS.SendText(contact.Peoples[i].CellPhone); }
將串行運算轉換為平行運算:
如下程式碼,可將串行運算裡的迴圈,由 TPL 底層自動拆成多個工作,同时指派給多個CPU,在程式碼撰寫上不需要花費太多的力氣。
Parallel.For(0, contact.Peoples.Count, i => { SMS.SendText(contact.Peoples[i].CellPhone); });
平行運算示意圖:
為什麼要用TPL? System.Threading.Thread Class & System.Threading.TheadPool Class V.S System.Thread.Tasks.Task Class
TPL(System.Thread.Task) 跟傳統執行緒 (System.Threading) 的執行結果沒有太大的異處,在沒有使用 TPL 以前,需要一堆程式碼來處理執行緒的『完成』、『取消』、『失敗』通知動作,但是 TPL 可以我們省掉了不少功夫,雖然兩者的運行結果相同,但底層的運行方式對軟體的效能能夠提昇,當然,要有效能上的提升前提之下是要有正確的流程。
有關執行緒的硬底子,可以參考
http://tl.zxhsd.com/kgsm/ts/big5/2012/02/02/2167932.shtml
.NET 3.5 執行緒寫法
ThreadPool.QueueUserWorkItem(_ => { //TODO:要做的事 });
.NET 4.0 TPL 寫法
Task t = new Task(() => { //TODO:要做的事 }); Task.Factory.StartNew(() => { //TODO:要做的事 }); Parallel.Invoke(() => { //TODO:要做的事 });
.NET 4.5 TPL 寫法
Task.Run(() => { //TODO:要做的事 });
可以看出在用法上傳統執行緒的用法跟 TPL 沒什麼兩樣,但其實在實作細節上 TPL 可以省掉很多很多的工,這在後面會再提到。
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET