简体   繁体   English

异步 lambda:“任务被取消”

[英]Async lambda: "a task was cancelled"

Here's the workflow:这是工作流程:

  1. Incoming HTTP request to WebApi2 endpoint.对 WebApi2 端点的传入 HTTP 请求。
  2. Make synchronous (eg not async) call to get some data.进行同步(例如非异步)调用以获取一些数据。
  3. Map response from DB entity to API model.将响应从数据库实体映射到 API 模型。 a.一种。 Executes AutoMapper mapping.执行 AutoMapper 映射。 b.Includes the following snippet (see below).包括以下代码段(见下文)。 c. C。 If operation is "quick", no issue.如果操作“快速”,则没有问题。 If operation is "slow", then "a task was cancelled" exception is thrown.如果操作“慢”,则抛出“任务被取消”异常。

I get lucky in cases when the mapping action is quick.在映射操作很快的情况下,我很幸运。 But if I add a Task.Delay(2000) , then I get the exception in question.但是如果我添加一个Task.Delay(2000) ,那么我就会得到有问题的异常。 It seems that ASP.NET is not "waiting" for my async lamba to complete?似乎 ASP.NET 没有“等待”我的异步 Lamba 完成?

Here is the body of the mapping expression:这是映射表达式的主体:

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
    }
});

Note that this is example code, and I don't intend to make additional DB/repo calls during mapping in "real life".请注意,这是示例代码,我不打算在“现实生活”中的映射期间进行额外的 DB/repo 调用。

AfterMap takes an Action , which is a synchronous delegate, not an asynchronous delegate (as I explain on my blog). AfterMap接受一个Action ,它是一个同步委托,而不是一个异步委托(正如我在我的博客中解释的那样)。 As such, it does not work as expected with async lambdas.因此,它在async lambda 表达式中无法按预期工作。

In this case (since the delegate returns void ), the compiler will actually allow an async lambda;在这种情况下(因为委托返回void ),编译器实际上将允许async lambda; however, it will compile to an async void method.但是,它将编译为async void方法。 (The compiler does this to allow async event handlers). (编译器这样做是为了允许async事件处理程序)。 As I describe in my MSDN article on async best practices, you should avoid async void .正如我在关于异步最佳实践的 MSDN 文章中所述,您应该避免使用async void

One of the reasons to avoid async void is that it is very difficult to detect when an async void method has completed.避免async void的原因之一是很难检测到async void方法何时完成。 In fact, (with the exception of WebForm lifetime events), ASP.NET will not even attempt to do so.事实上,(除了 WebForm 生命周期事件),ASP.NET 甚至不会尝试这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM