Async lambda:“任务被取消”

本文关键字:取消 任务被取消 任务 lambda Async | 更新日期: 2023-09-27 18:07:19

工作流程如下:

  1. 向WebApi2端点传入HTTP请求。
  2. 进行同步(例如,不是异步)调用以获取一些数据。
  3. 映射数据库实体到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调用。

Async lambda:“任务被取消”

AfterMap接受Action,这是一个同步委托,而不是异步委托(正如我在我的博客上解释的那样)。因此,它不能像预期的那样与async lambdas一起工作。

在这种情况下(因为委托返回void),编译器实际上会允许async lambda;但是,它将编译为async void方法。(编译器这样做是为了允许async事件处理程序)。正如我在MSDN上关于异步最佳实践的文章中所描述的那样,您应该避免使用async void

避免async void的原因之一是当async void方法完成时很难检测到。事实上,(除了WebForm生命周期事件),ASP。. NET甚至不会尝试这样做