萬劍齊發
小明同學,回家又把自己的早餐店模擬程式優化了一版,已經可以輕鬆模擬多條早餐流水線了!趨於完美。不過細心的小明從來不會讓我失望,他就跟我說道,老師,TPL不會只提供了Task這一個類吧!肯定還有其他先進的,好用的工具類等著我們去發現!
今天我們就再來說一個TPL中的工具類:Parallel。
例項演示首先我們來看一種更簡單的開啟多工的方法:
class Program{ static void Main(string[] args) { Console.WriteLine("Hello Parallel World!"); Parallel.Invoke(Func1, Func2); Console.WriteLine("Run Finished!"); } static void Func1() { for (int i = 0; i < 3; i++) { Task.Delay(888).Wait(); Console.WriteLine($"Func1 Running"); } } static void Func2() { for (int i = 0; i < 3; i++) { Task.Delay(666).Wait(); Console.WriteLine($"Func2 Running"); } }}
執行結果如下:
並行執行
可以看出,使用Parallel.Invoke同時開啟多個任務,是非常簡單的,其引數是可變的,可以同時傳入多個任務。而且不需要對Parallel.Invoke進行等待操作。只有其引數中傳入的任務全部執行完畢時,才會執行Parallel.Invoke之後的程式碼。在某些場景,還是很好用的。
此外,Parallel中還有兩個主要函式:
Parallel.ForParallel.Foreach這兩個函式,和普通的for和foreach功能類似,但是這兩者是並行執行的。也就是使用多執行緒來執行迴圈或者遍歷集合:
Console.WriteLine("Hello Parallel World!");Parallel.For(0,20, (i) =>{ var tid = Thread.CurrentThread.ManagedThreadId; Console.WriteLine($"Current index: {i}, " + $"ThreadId: {tid}");});Console.WriteLine("Run Finished!");
執行結果如下:
多個執行緒並行亂序執行
可以看到,並行執行的情況,和ThreadPool非常像:
執行緒的數量較少執行緒可以重複使用執行的順序是隨機的還的帶模板引數TLocal的版本,TLocal為每個執行緒提供了一個本地變數,可以在多個執行緒之間傳遞資料,這個變數是執行緒專用的,相比外部的普通變數,可以減少對變數加鎖的開支,效率更高。在某些場景下用得上。
此外,Parallel.For還提供了兩個輔助類,方便我們使用:
ParallelOptions這個類,提供一些高階引數:MaxDegreeOfParallelism可以控制開啟執行緒的數量,在處理非CPU密集型的任務時,可以適當多開啟一些執行緒,可以提升處理效率;CancellationToken可以控制如何取消迴圈。
ParallelLoopState這個類,提供了另一種跳出迴圈的方法Break,這個和普通的迴圈比較類似了。但是其退出迴圈的時機,還是不精確。
Parallel.Foreach的使用方法和Parallel.For是類似的,只是操作物件變成了集合了。在對大量資料進行並行處理時,不用我們對資料進行分組了,Parallel自動幫我們完成,並自動排程,使用更簡單。
佈置作業練習使用Parallel.Foreach。
小明的臉上,還是掛著迷之微笑!
小明你倒是把紅包送給老師啊
踩坑記錄暫無
下期預告下面是給同學們準備的乾貨,正在陸續發貨中哦:
Linq與PLinq (ParallelEnumerable)
await/async
。。。 。。。