ActionBlock<T> 对比 Task.WhenAll

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;

这两种方法都可以接受,选择应根据您的要求而定,因为您可以看到 Dataflow 为您提供了很多可配置性,否则您在直接使用 Tasks 时必须手动实施这些可配置性。

请注意,在这两种情况下,任务池都将负责排队和 运行 任务,因此行为应该保持不变。

Dataflow 擅长将可组合的异步操作组链接在一起,而使用任务可以让您进行更细粒度的控制。

I would like to know what is the recommended way to execute multiple async methods in parallel?

旁注:实际上不是并行,而是并行

in System.Threading.Tasks.Dataflow we can specify the max degree of parallelism but unbounded is probably the default for Task.WhenAll too ?

正如有人评论的那样,Task.WhenAll 仅加入现有任务;当您的代码到达 Task.WhenAll 时,所有并发决策都已完成。

您可以使用 SemaphoreSlim.

之类的东西来限制纯异步代码

直接使用异步并发还是TPL Dataflow取决于周边代码。如果这个并发操作只被异步调用一次,那么异步并发是最好的选择;但如果此并发操作是您数据的 "pipeline" 的一部分,那么 TPL 数据流可能更合适。