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

C# async/await结合LINQ Select实现CSV导出异常问题

问题核心原因

Select方法传入async委托时,返回值类型是IEnumerable<Task<T>>,你当前代码直接将这个Task集合作为导出结果返回,CSV导出组件遍历数据源时拿到的都是未等待执行的Task对象,反射读取属性时只能读到Task类型自带的Id、Status、AsyncState等属性,完全读不到你封装的业务字段,因此导出的文件没有任何有效内容。

异常截图

修复代码

使用Task.WhenAll等待所有异步数据查询任务执行完成,拿到实际的匿名对象集合后再返回给导出组件:

private async Task<IEnumerable> OnExport(SearchCriteria cr)
{
    var sr = await GetResult(cr);
    var results = sr.Results;
    // 构造所有数据查询任务
    var exportQueryTasks = results.Select(async export =>
    {
        var data = await dataService.GetById(export.Id);
        var pAddress = export.ContactInformation?.Addresses.FirstOrDefault(x => x.AddressType == Framework.Contracts.Enums.AddressTypes.Physical);
        var mAddress = export.ContactInformation?.Addresses.FirstOrDefault(x => x.AddressType == Framework.Contracts.Enums.AddressTypes.Mailing);
        return new
        {
            LegalBusinessName = export.Name,
            DBA = export.DBAName,
            BusinessEmail = export.ContactInformation?.PrimaryEmail,
            PhonePrimary = export.ContactInformation?.PrimaryPhone,
            PhoneTypePrimary = export.ContactInformation?.PrimaryPhoneType,
            PhoneSecondary = export.ContactInformation?.SecondaryPhone,
            PhoneTypeSecondary = export.ContactInformation?.SecondaryPhoneType,
            Website = export.WebAddress,
            PhysicalStreetAddress = pAddress?.Address1,
            PhysicalAddressLine2 = pAddress?.Address2,
            PhysicalCity = pAddress?.City,
            PhysicalCounty = pAddress?.County,
            PhysicalState = pAddress?.State,
            PhysicalZipCode = pAddress?.Zip,
            MailingStreetAddress = mAddress?.Address1,
            MailingAddressLine2 = mAddress?.Address2,
            MailingCity = mAddress?.City,
            MailingCounty = mAddress?.County,
            MailingState = mAddress?.State,
            MailingZipCode = mAddress?.Zip,
            SchoolOnboarding = data?.ConfirmedVideo,
            SchoolStartDate = data?.SchoolStartDate,
            SchoolEndDate = data?.SchoolEndDate,
            Grades = string.Join(",", data?.GradeLevels.Select(x => x.GradeLevel)),
            IsReligiousSchool = data?.ConfirmedIsReligious,
            ReligiousAffiliation = data?.ReligiousAffiliation,
            TCSignatureName = export.SignatureName,
            TCDateSigned = export.TermsAcceptedOn
        };
    });
    // 等待所有任务执行完成,拿到实际业务数据
    var exportData = await Task.WhenAll(exportQueryTasks);
    return exportData;
}
额外注意事项
  • 检查OnExport方法的调用处是否添加了await关键字,如果未await,方法返回的是Task<IEnumerable>对象本身,同样会导致导出组件读不到有效数据。
  • 当导出数据量较大时,不建议在循环中逐条调用GetById查询数据,会产生大量数据库/IO请求,容易触发连接池限制、超时等问题,建议替换为批量查询接口,根据所有Id一次性拉取全量关联数据。
  • 多数CSV导出组件不支持自动解析异步任务包装的数据源,传入导出组件的必须是已经执行完成的同步业务数据集合。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:30:51