簡體   English   中英

Parallel.ForEach和await ForEachAsync之間的區別

[英]Differences between Parallel.ForEach and await ForEachAsync

在任何情況下,是否有任何理由選擇Para​​llel.ForEach而不是等待ForEachAsync(反之亦然)? 還是它們幾乎相同?

await collection.ForEachAsync( m => { m.DoSomething(); } );

VS

Parallel.ForEach( collection, m => { m.DoSomething(); } );

它們根本不是“幾乎相同”的。

當您使用Parallel類中的函數Parallel.ForEach()例如Parallel.ForEach()您正在調用某些操作,該操作分為多個較小的操作,每個操作在不同的線程(又稱為多線程)上執行。

ForEachAsync ,另一方面不一定多線程。 它是異步的,並且異步操作不是多線程的(它們可以,但不一定是,這取決於實現)。

我強烈建議閱讀以下帖子 ,其中將詳細介紹該主題。

至於你的問題

在任何情況下是否有任何理由選擇Para​​llel.ForEach而不是等待ForEachAsync

答案是絕對肯定有這樣做的理由,但是為了確定您將使用哪種方案,您必須同時了解它們。

這是一個簡單的例子:

您有一組對象,並且想要對其進行迭代並執行某種操作。 您是否關心這些動作的發生順序? 如果是這樣,請不要使用Parallel.ForEach()因為不能保證調用它們的順序(由於其多線程性質)。

編輯:

在您的示例中,這全都取決於collection有多少項以及多處理DoSomething()程度。

這樣做的原因是因為Parallel.ForEach() 不是free 需要權衡取舍。 設置多線程環境會花費一些時間,並且如果collection很小並且/或者DoSomething()不會花費長時間,那么設置這些線程所花費的時間會比使用單線程異步時更好(通常更快)。操作。

另一方面,如果collection量很大和/或DoSomething()是一個繁重的任務,則Parallel.ForEach()將絕對是性能最高的選項。

一切都取決於線程,假設您有以下課程

public class person
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }

這是你的主要班級

List<person> persons = new List<person>()
            {
                new person{ ID = 1,Name="Ali"}
                ,new person{ ID = 2,Name="Gorge"}
                ,new person{ ID = 3,Name="Alex"}
                ,new person{ ID = 4,Name="Liz"}
                ,new person{ ID = 5,Name="Scott"}
                ,new person{ ID = 6,Name="Abby"}
                ,new person{ ID = 7,Name="Sarah"}
            };

            Parallel.ForEach(persons, (p) =>
            {
                Console.WriteLine($"Id : {p.ID} ,Name : {p.Name}");
            });

當您運行此代碼時,列表項將通過diff線程拆分,並且代碼不會按順序運行,如您在以下輸出中看到的那樣,我得到的打印順序與原始List的diff順序相同 在此處輸入圖片說明

在這里我再次運行相同的代碼,但是我得到了差異結果

在此處輸入圖片說明

由於線程的原因,編譯器將線程划分為多個,並且每個列表都運行分配給它的項,下圖顯示了diff線程

在此處輸入圖片說明

但是當您運行以下代碼時

List<person> persons = new List<person>()
            {
                new person{ ID = 1,Name="Ali"}
                ,new person{ ID = 2,Name="Gorge"}
                ,new person{ ID = 3,Name="Alex"}
                ,new person{ ID = 4,Name="Liz"}
                ,new person{ ID = 5,Name="Scott"}
                ,new person{ ID = 6,Name="Abby"}
                ,new person{ ID = 7,Name="Sarah"}
            };

            await persons.ForEachAsync(async p => Console.WriteLine($"Id : {p.ID} ,Name : {p.Name}"));

你只有一個線程顯示在這里

在此處輸入圖片說明

再加上數據打印將始終按照列表的相同順序運行

我希望這個答案能解釋差異!

在任何情況下,是否有任何理由選擇Para​​llel.ForEach而不是等待ForEachAsync(反之亦然)?

Parallel.ForEach用於同步代碼。 它的委托必須是同步的,並且必須被同步調用。

ForEachAsync不是標准算法。 有幾種不同的實現,但是通常它們會嘗試將異步和並行性混合在一起。 他們必須放棄一些Parallel.ForEach的自我平衡方面。 絕大多數代碼不需要ForEachAsync ; 大多數代碼是異步平行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM