Async lambda:“任务被取消”
本文关键字:取消 任务被取消 任务 lambda Async | 更新日期: 2023-09-27 18:07:19
工作流程如下:
- 向WebApi2端点传入HTTP请求。 进行同步(例如,不是异步)调用以获取一些数据。
- 映射数据库实体到API模型的响应。a.执行AutoMapper映射。b.包括以下代码片段(见下文)。c.如果操作"快",没有问题。如果操作"缓慢",则抛出"任务被取消"异常。
如果映射动作很快,我就会很幸运。但如果我加上一个Task.Delay(2000)
,就会得到问题中的异常。似乎ASP。. NET不是"等待"我的异步lamba完成?
下面是映射表达式的主体:
mapping.AfterMap(async (entity, model) => {
var child = await _childRepo.Get(entity.ChildId);
await Task.Delay(2000); // For testing, of course.
if (child != null)
{
// Fill in some properties on model
}
});
请注意,这是示例代码,我不打算在"现实生活"的映射过程中进行额外的DB/repo调用。
AfterMap
接受Action
,这是一个同步委托,而不是异步委托(正如我在我的博客上解释的那样)。因此,它不能像预期的那样与async
lambdas一起工作。
在这种情况下(因为委托返回void
),编译器实际上会允许async
lambda;但是,它将编译为async void
方法。(编译器这样做是为了允许async
事件处理程序)。正如我在MSDN上关于异步最佳实践的文章中所描述的那样,您应该避免使用async void
。
避免async void
的原因之一是当async void
方法完成时很难检测到。事实上,(除了WebForm生命周期事件),ASP。. NET甚至不会尝试这样做