【发布时间】:2020-04-24 16:52:17
【问题描述】:
我一直在玩 async/await 并发现了一些有趣的东西。看看下面的例子:
// 1) ok - obvious
public Task<IEnumerable<DoctorDto>> GetAll()
{
IEnumerable<DoctorDto> doctors = new List<DoctorDto>
{
new DoctorDto()
};
return Task.FromResult(doctors);
}
// 2) ok - obvious
public async Task<IEnumerable<DoctorDto>> GetAll()
{
IEnumerable<DoctorDto> doctors = new List<DoctorDto>
{
new DoctorDto()
};
return await Task.FromResult(doctors);
}
// 3) ok - not so obvious
public async Task<IEnumerable<DoctorDto>> GetAll()
{
List<DoctorDto> doctors = new List<DoctorDto>
{
new DoctorDto()
};
return await Task.FromResult(doctors);
}
// 4) !! failed to build !!
public Task<IEnumerable<DoctorDto>> GetAll()
{
List<DoctorDto> doctors = new List<DoctorDto>
{
new DoctorDto()
};
return Task.FromResult(doctors);
}
考虑情况 3 和 4。唯一的区别是 3 使用 async/await 关键字。 3 构建良好,但是 4 给出了关于将 List 隐式转换为 IEnumerable 的错误:
Cannot implicitly convert type
'System.Threading.Tasks.Task<System.Collections.Generic.List<EstomedRegistration.Business.ApiCommunication.DoctorDto>>' to
'System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<EstomedRegistration.Business.ApiCommunication.DoctorDto>>'
这里的 async/await 关键字发生了什么变化?
【问题讨论】:
-
1和4有什么区别?我是不是瞎了眼了?
-
基于问题(编译器输出)我认为实际代码中的 4 有
List<DoctorDto> doctors = new ...对吗? ...是的 -
@CarstenKönig 你是对的 - 更正它
-
@Hammerstein 我的错应该是 List 而不是 IEnumerable,我刚刚纠正了它。
-
@gisek 原因很简单——
await将Task<List<DoctorDto>>中的值解包,因此得到List<DoctorDto>。然后async方法中的return将其包装回任务中 - 但由于它应该返回Task<IEnumerable<DoctorDto>>而不是Task<List<DoctorDto>>,因此它将执行显式转换。您不能将Task<List<DoctorDto>>转换为Task<IEnumerable<DoctorDto>>,但您可以 将List<DoctorDto>转换为IEnumerable<DoctorDto>>- 所以您只需要转换有效负载即可。return await为您处理。
标签: c# .net asynchronous