如何将List<Task<AttachmentRequestModel>>转换为List<AttachmentRequestModel>
问题解决与优化方案
为什么原代码返回List<Task<AttachmentRequestModel>>?
因为你在Select中使用了async lambda表达式,所有async方法都会返回Task或Task<T>,因此Select最终生成的是IEnumerable<Task<AttachmentRequestModel>>,调用ToList()后自然得到List<Task<AttachmentRequestModel>>。
更优的实现方式:Task.WhenAll
你当前的循环逐个await是串行执行异步任务,效率较低(前一个任务完成后才会启动下一个)。推荐使用Task.WhenAll并行等待所有任务完成,一次性获取结果,这在IO密集型场景(比如读取附件内容)下能大幅提升效率。
代码示例
// 生成所有异步任务 var attachmentTasks = recordAction .PPAttachments .Select(async x => new AttachmentRequestModel() { AttachmentId = 1, AttachmentContent = await GetReportAttachContentAsync(1), AttachmentName = "name", AttachmentType = 1 }) .ToList(); // 并行等待所有任务完成,直接得到结果数组 var attachmentList = (await Task.WhenAll(attachmentTasks)).ToList();
或者合并为更简洁的写法:
var attachmentList = await Task.WhenAll( recordAction.PPAttachments.Select(async x => new AttachmentRequestModel() { AttachmentId = 1, AttachmentContent = await GetReportAttachContentAsync(1), AttachmentName = "name", AttachmentType = 1 }) ).ConfigureAwait(false); // 非UI场景可添加ConfigureAwait(false),避免上下文死锁风险
注意事项
- 确保当前方法标记为
async,否则无法使用await关键字。 - 如果
GetReportAttachContentAsync是CPU密集型操作,并行执行可能不会带来性能提升(甚至因线程切换产生额外开销),但附件内容读取通常属于IO密集型,并行更合适。
内容的提问来源于stack exchange,提问作者Voice Of The Rain
相关产品推荐
相关产品推荐

