三分鐘總覽微軟任務並行庫TPL
點選上方 藍字 進行關注
有小夥伴問我每天忽悠的TPL是什麼?
☹️ 這次站位高一點,嚴肅講一講。
引言
俗話說,不想開飛機的程式設計師不是一名好爸爸;作為微軟技術棧的老鳥,一直將程式碼整潔之道奉為經典, 優秀的程式設計師將優雅、高效能的程式碼看成自己的臉面。
今天探討下我對.NET並行程式設計庫 Task Parallel Library
的理解,開足馬力,準備壓榨CPU了。

技術背景
硬體執行緒和軟體執行緒
多核處理器帶有一個以上的物理核心:物理核心是真正的獨立處理單元,多個物理核心使得多條指令能夠同時並行執行。
硬體執行緒也稱為邏輯核心,一個物理核心可能會使用超執行緒技術提供多個硬體執行緒,所以一個硬體執行緒並不代表一個物理核心。程式通過 Environment.ProcessorCount
得到的就是邏輯核心(本人的機器是i5-5300U 虛擬4核), Windows中每個執行的程式都是一個程序,每一個程序都會建立並執行一個或多個執行緒,這些執行緒稱為軟體執行緒,硬體執行緒就像是一條泳道,而軟體執行緒就是在其中游泳的人。
並行場 景
.NET引入的Task Parallel Library(任務並行庫,TPL),動態地擴充套件併發度,以最有效的方式使用所有可用的處理器。
另外TPL支援分割槽工作、支援基於ThreadPool排程、支援取消非同步操作、支援狀態管理。
通過TPL專注與讓程式完成你業務意義上的任務,同時最大限度的提高程式效能。
TPL同時支援資料並行、任務並行和流水線Dataflow
1.
資料並行
:有大量資料需要處理,並且必須對每一份資料執行同樣的操作;
2.
任務並行
:通過任務併發執行不同的操作;
3.
流水線
:任務並行和資料並行的結合體 (需要引入System.Threading.Tasks.Dataflow元件庫)
其中1、3 已經在上文演示,本文就隨手拿資料並行、任務並行聊一聊。
程式設計實踐
1. 資料並行
找到100000以內素數的個數
上文[共享記憶體併發模型],程式碼可做如下優化:
由每個執行緒獨立計算執行緒內迭代產生的素數和,最後再對幾個和求和 。
using System; using System.Threading.Tasks; using System.Collections; using System.Collections.Generic; using System.Threading; using System.Diagnostics; /// <summary> /// 利用並行程式設計庫Parallel,計算100000內素數的個數 /// </summary> namespace Paralleler { class Program { static void Main(string[] args) { Stopwatch sw = new Stopwatch(); sw.Start(); ShareMemory(); sw.Stop(); Console.WriteLine($"優化後的共享記憶體併發模型耗時:{sw.Elapsed}"); } static void ShareMemory() { var sum = 0; Parallel.For(1, 100000 + 1, () => 0, (x, state, local) => { var f = true; if (x == 1) f = false; for (int i = 2; i <= x / 2; i++) { if (x % i == 0) // 被[2,x/2]任一數字整除,就不是質數 f = false; } if (f == true) local++; return local; }, local => { Interlocked.Add(ref sum, local); } ); Console.WriteLine($"1-100000內質數的個數是{sum}"); } } }
引數1,2 表示資料並行要操作的物件;
引數3localInit
表示某執行緒內迭代的初始值,將會作為引數4body
委託的第3個引數,只在執行緒第一次使用;
引數4body
表示每個迭代都需要經歷的執行體, 這裡以執行緒為單元處理迭代;引數5
localFinally
對每個執行緒的輸出再做一次計算,入參是引數4的輸出。
2. 任務並行
讓許多方法並行執行的最簡單的方法就是使用Parallel類的 Invoke
方法, Invoke方法接受一個Action的引數組
void System.Threading.Tasks.Parallel.Invoke(WatchMovie, HaveDinner, ReadBook, WriteBlog);
這段程式碼會建立指向每一個方法的委託。
沒有特定的執行順序
Parallel.Invoke方法只有在4個方法全部完成之後才會返回。它至少需要4個硬體執行緒才足以讓這4個方法併發執行。
但並不保證這4個方法能夠同時啟動執行,如果一個或者多個核心處於繁忙狀態,那麼底層的排程邏輯可能會延遲某些方法的初始化執行。
捕捉並行迴圈中發生的異常
當並行迭代中呼叫的委託丟擲異常,這個異常沒有在委託中被捕獲到時,就會變成一組異常,新的 System.AggregateException
負責處理這一組異常。
本文為微軟TPL入門級教程,學習一個專題,瞭解特性/能力最重要, 剩下的就是結合場景去應用。
本文內容和製圖均為原創,文章永久更新地址請參閱左下角原文,如對您有所幫助,【在看、點贊】來一發,未嘗不可 。
往期 精彩 回顧
.NET Core實戰專案之CMS 第一章 入門篇-開篇及總體規劃
【.NET Core微服務實戰-統一身份認證】開篇及目錄索引
Redis基本使用及百億資料量中的使用技巧分享(附影片地址及觀看指南)
.NET Core中的一個介面多種實現的依賴注入與動態選擇看這篇就夠了
用abp vNext快速開發Quartz.NET定時任務管理介面
- ASP.NET Core在.NET 7 RC1中的更新
- 如何設計一個支援百萬使用者的系統
- 分享一個基於.NET6包含DDD,ES,CQRS等概念的開源專案
- [第二篇]如何在ASP.Net Core的生產環境中使用OAuth保護swagger ui
- 如何在C#中使用Channels進行非同步排隊
- 話說C#程式設計師人手一個ORM
- 快速理解ASP.NET Core的認證與授權
- 如何在 C# 中使用 插值字串?
- C#10在List, Queue 以及Stack中使用EnsureCapacity方法來提升效能
- 如何主動清空.NET資料庫連線池?
- 基於 gRPC 和 .NET Core 的伺服器流
- 三分鐘總覽微軟任務並行庫TPL
- .NET 6 Preview5 VS2022實戰千萬併發秒殺專案,帥爆了(附原始碼)
- c#如何建立使用者自定義異常?
- 讓Dapper在一個專案中支援多種庫
- 深入LINQ | 動態構建LINQ表示式
- C# 並行和多執行緒程式設計——認識和使用Task
- C# 動態編譯簡介
- C#中HashTable、Dictionary、ConcurrentDictionary區別
- 微軟強推!64位Visual Studio 2022帶來這些新變化!