首頁>技術>

萬劍齊發

小明同學,回家又把自己的早餐店模擬程式優化了一版,已經可以輕鬆模擬多條早餐流水線了!趨於完美。不過細心的小明從來不會讓我失望,他就跟我說道,老師,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

。。。 。。。

24
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 圖解java資料結構之棧(Stack),你確定不看看嗎?