2

我想知道什麼是並行執行多個異步方法的推薦方式?ActionBlock <T> vs Task.WhenAll

在System.Threading.Tasks.Dataflow中,我們可以指定最大並行度,但無界可能是Task.WhenAll的默認值?

這樣的:

var tasks = new List<Task>(); 
foreach(var item in items) 
{ 
    tasks.Add(myAsyncMethod(item)); 
} 
await Task.WhenAll(tasks.ToArray()); 

,或者:

var action = new ActionBlock<string>(myAsyncMethod, new ExecutionDataflowBlockOptions 
     { 
      MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded, 
      BoundedCapacity = DataflowBlockOptions.Unbounded, 
      MaxMessagesPerTask = DataflowBlockOptions.Unbounded 
     }); 
foreach (var item in items) { } 
{ 
    action.Post(item); 
} 
action.Complete(); 

await action.Completion; 
+0

'Parallel.ForEach()'? –

+1

並行和異步混合不好,並且這些方法是異步的(我無法更改它們) –

+1

您顯示的'Task.WhenAll'代碼與並行執行任務無關 - 任何有關使用例如線程池線程,並行等等,都發生在'myAsyncMethod'裏面(大概是)返回熱的Task。 –

回答

1

我想知道什麼是並行執行多個異步方法的推薦方式?

邊注:實際上不是平行,但併發

在System.Threading.Tasks.Dataflow中,我們可以指定最大並行度,但無界可能是Task.WhenAll的默認值?

正如有人評論,Task.WhenAll只加入現有的任務;當你的代碼到達Task.WhenAll時,所有的併發性判斷已經完成。

您可以通過使用諸如SemaphoreSlim之類的東西來節制純異步代碼。

決定是直接使用異步併發還是TPL數據流取決於周圍的代碼。如果這個併發操作只是異步調用一次,那麼異步併發是最好的選擇;但如果此併發操作是數據的「管道」的一部分,那麼TPL Dataflow可能更適合。

0

這兩種方法是可以接受的選擇應該由你的要求來管理,你可以看到數據流給你很多的可配置性,你會否則必須直接使用任務時手動實現。

請注意,在這兩種情況下,任務池將負責排隊和運行任務,因此相同的行爲應該保留相同的行爲。

數據流擅長將可組合的異步操作組鏈接在一起,而使用任務爲您提供更細粒度的控制。

+0

好吧,如果只是爲了並行而不把它鏈接成沒有真正的好處? –

+0

如果你不需要鏈接或組合,它可能會過度殺傷,是的 – Slugart