You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# Async/Await使用疑问:是否需等待异步任务完成再合并结果

结论

你当前的Async/Await写法不是最高效实现,且结果合并操作必须等两个异步任务全部执行完成后才能执行。

现有实现的性能问题

你现在写的两个await是串行执行逻辑:代码执行到第一个await GetAdHocReports(days)时,会等待该方法完全返回结果后,才会启动GetPushReports(days)的调用。这两个查询操作互相没有依赖,完全可以并发执行,串行等待会白白多消耗一倍左右的IO等待时间。

合并操作的时机要求

必须等两个任务全部执行完成后再合并结果。合并逻辑需要拿到两个查询返回的完整数据集,任意一个任务没完成都无法拿到完整数据做合并,提前操作要么会阻塞线程,要么会抛出异常、拿到不完整结果。

优化后的高效实现

先同时启动两个异步任务,再通过Task.WhenAll等待两个任务全部完成后做结果合并即可,优化后总耗时约等于两个查询中耗时更长的那个,而非两个查询耗时的总和,参考代码:

public async Task<IEnumerable<Reports>> GetReports(int days = 0)
{
    // 同时启动两个异步查询任务,不立即等待
    var adHocReportsTask = GetAdHocReports(days);
    var pushReportsTask = GetPushReports(days);

    // 等待两个任务全部执行完成
    await Task.WhenAll(adHocReportsTask, pushReportsTask);

    // 两个任务均已完成,直接取结果合并无额外阻塞
    var result = new List<Reports>();
    result.AddRange((List<Reports>)adHocReportsTask.Result);
    result.AddRange((List<Reports>)pushReportsTask.Result);
    return result;
}

注意事项

  • 如果你的数据库连接没有开启MARS(多活动结果集),同一个连接不支持同时执行多个查询,这种场景下并发执行会抛出异常,此时保留原有的串行await写法即可。
  • 不要在Task.WhenAll执行完成前调用任务的Result属性,否则会阻塞当前线程,失去异步的优势。

内容的提问来源于stack exchange,提问作者user17176542

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 17:48:20