ActionBlock <t> vs Task.WhenAll

时间:2016-05-16 08:34:53

标签: c# asynchronous async-await task-parallel-library tpl-dataflow

我想知道并行执行多个异步方法的推荐方法是什么?

在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;

2 个答案:

答案 0 :(得分:1)

这两种方法都是可以接受的,并且选择应该由您的要求决定,因为您可以看到Dataflow为您提供了大量的可配置性,否则您在直接使用任务时必须手动实现。

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

Dataflow擅长将可组合的异步操作组合在一起,而使用任务可以为您提供更细粒度的控制。

答案 1 :(得分:1)

  

我想知道并行执行多个异步方法的推荐方法是什么?

附注:实际上不是 parallel ,而是并发

  在System.Threading.Tasks.Dataflow中我们可以指定最大并行度,但是无界可能是Task.WhenAll的默认值吗?

有人评论说,Task.WhenAll只加入现有的任务;当你的代码到达Task.WhenAll时,所有的并发决定都已经完成了。

您可以使用SemaphoreSlim

之类的内容来限制普通的异步代码

是否直接使用异步并发或TPL Dataflow的决定取决于周围的代码。如果这个并发操作只是异步调用一次,那么异步并发是最好的选择;但如果这个并发操作是数据“管道”的一部分,那么TPL Dataflow可能更适合。