嵌套的Async/Await似乎没有伸缩

本文关键字:Async Await 嵌套 | 更新日期: 2023-09-27 17:53:20

我有以下(简化)代码:

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());
}

根据我所看到的,它似乎不是很好地扩展。所有的Async操作都是"真正的异步"操作,这意味着它们都是I/o。

我使用Async/Await不正确的情况下?根据我目前的观察,它并没有达到我的预期。TPL数据流是我的解决方案吗?

嵌套的Async/Await似乎没有伸缩

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

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