嵌套的异步/等待似乎不会缩放

Cam*_*ron 5 c# asynchronous async-await tpl-dataflow

我有以下(简化)代码:

public async Task GetData(DomainObject domainObject, int depth)
{
  // This async operation is really quick, and there's usually like five.
  IEnumerable<TierOne> tierOnes = await domainObject.GetTierOnesAsync();

  var tierOneTasks = tierOnes.Select(async tierOne => 
  {
    // This async operation is really quick and there's usually like three.
    IEnumerable<TierTwo> tierTwos = await tierOne.GetTierTwosAsync();

    if (depth <= TierTwoDepth)
      return;

    var tierTwoTasks = tierTwos.Select(async tierTwo => 
    {
      // This async operation is usually fast, and there's usually >= 100.
      IEnumerable<TierThree> tierThrees = await tierTwo.GetTierThreesAsync();

      if (depth <= TierThreeDepth)
        return;

      var tierThreeTasks = tierThrees.Select(async tierThree => 
      {
        // This async operation is SLOW, and there's usually.. 50?
        await tierThree.GetTierFoursAsync();
      });

      await Task.WhenAll(tierThreeTasks.ToArray());
    });

    await Task.WhenAll(tierTwoTasks.ToArray());
  });

  await Task.WhenAll(tierOneTasks.ToArray());
}
Run Code Online (Sandbox Code Playgroud)

基于我所看到的,它似乎没有很好地扩展.所有Async操作都是"真正的异步"操作,这意味着它们都是I/O.

我是否在这种情况下错误地使用Async/Await?根据我目前的观察结果,它没有按照我的预期进行扩展.TPL DataFlow会成为我的解决方案吗?

Joe*_*ung 0

对于对 的单个调用GetData,嵌套的 async/await 调用不会引入任何并发性。您检索所有 tierOne,然后检索 tierOne-#1 的所有 tierTwo,然后检索 tierTwo-#1 的所有 tierThrees,依此类推,所有这些都按顺序运行(尽管 GetTier*Async 方法内部可能存在一些并发)。

如果你想要并发请求,那么TPL Dataflow确实是一个更好的解决方案。