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

异步Lambda表达式编译失败,寻求正确async/await使用方案

异步Select构建对象数组的正确实现方式

问题根源

你当前的代码中,Select(async s => ...)会返回IEnumerable<Task<ResourcesResponse.Resource>>,直接调用.ToArray()得到的是Task<ResourcesResponse.Resource>[],但ResourcesResponse.Resources属性要求的是ResourcesResponse.Resource[],类型不匹配导致编译失败。同时异步任务必须被等待才能拿到实际对象,不能用.Result阻塞线程。

解决方案

拆分异步任务处理流程:先生成所有子资源的异步任务集合,再用Task.WhenAll()批量等待所有任务完成,最后将结果转为目标类型数组。

修改后的完整代码

// 先生成所有子资源的异步任务集合
var resourceTasks = aux
    .OrderBy(k => k.Order)
    .ThenBy(k => k.TypeId)
    .Select(async s => new ResourcesResponse.Resource
    {
        Id = ((ulong)s.Id).ToString(),
        Charge = s.Charge,
        Cost = s.Cost,
        CurrencyCode = s.CurrencyCode,
        ForecastCharge = s.ForecastCharge,
        ForecastCost = s.ForecastCost,
        ForecastUsedUnits = s.ForecastUsedUnits,
        ParentId = ((ulong?)s.ParentId).ToString(),
        Order = await _resourcesRepository.GetResourceTypeOrder(s.TypeId),
        Rate = s.Rate,
        TypeId = s.TypeId,
        UsedUnits = s.UsedUnits,
        // 注意:Resource类定义中的Type属性未在原代码赋值,需补充逻辑(示例调用仓储方法)
        Type = await _resourcesRepository.GetResourceTypeName(s.TypeId)
    });

// 等待所有异步任务完成,得到Resource数组
var resources = await Task.WhenAll(resourceTasks);

// 实例化ResourcesResponse
var tmp = new ResourcesResponse
{
    Cost = aux.Sum(s => s.Cost),
    Resources = resources,
    Id = ((ulong)entry.Id).ToString(),
    Name = entry.Name,
    Description = entry.Description,
    OriginalId = entry.OriginalId,
    ResourceTypeId = entry.ResourceTypeId,
    ResourceType = await _resourcesRepository.GetResourceTypeName(entry.ResourceTypeId),
    Order = await _resourcesRepository.GetResourceTypeOrder(entry.ResourceTypeId),
    State = entry.State,
    Zone = entry.Zone,
    Charge = aux.Sum(s => s.Charge),
};

性能优化建议

如果子资源存在大量重复的TypeId,可以批量获取所有需要的Order值,减少异步调用次数:

// 批量去重获取所有需要的TypeId
var distinctTypeIds = aux.Select(s => s.TypeId).Distinct();

// 批量发起异步请求并等待完成
var orderTaskMap = distinctTypeIds.ToDictionary(id => id, id => _resourcesRepository.GetResourceTypeOrder(id));
await Task.WhenAll(orderTaskMap.Values);

// 构建Order映射表(任务已完成,使用.Result不会阻塞)
var orderMap = orderTaskMap.ToDictionary(kv => kv.Key, kv => kv.Value.Result);

// 同步构建子资源数组
var resources = aux
    .OrderBy(k => k.Order)
    .ThenBy(k => k.TypeId)
    .Select(s => new ResourcesResponse.Resource
    {
        Id = ((ulong)s.Id).ToString(),
        // ...其他属性赋值
        Order = orderMap[s.TypeId],
        // ...其他属性
    })
    .ToArray();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 09:06:02