创建一个 returns 立即确定的异步控制器

Creating an asynchronous controller that returns OK immediately

我正在尝试将新的 async/await 功能与 webapi 相结合。

我想做的是:

我不想等待 B 的工作,然后才能return 向发送给 A 的请求发送 OK 消息。我希望能够致电 A 并得到 OK 回复在 B 上的工作仍在完成时尽快完成。

这可能吗?如果是这样,设计这样的东西的正确方法是什么?

感谢您的指点。

您可能想用 response code of 202 (accepted) 来响应调用者,以向客户端表明正在进行其他一些处理。 然后,如果您的客户需要额外的反馈,它可以进行长时间的轮询,或者您可以实施 websocket 等。

您想要的是在您的通话中触发 "Fire and Forget" 语义。

如果您使用的是 .NET 4.5.2,则可以使用 HostingEnvironment.QueueBackgroundWorkItem 在 ASP.NET 线程池线程上注册和排队工作。

如果您使用的是以前的版本,则可以使用 Stephan Cleary 的 BackgroundTaskManager

请注意,这与 async-await 无关。

示例如下所示:

public HttpResponseMessage Foo()
{
    HostingEnvironment.QueueUserWorkItem(() => { /* offloaded code here */ });
    return Request.CreateResponse(HttpStatusCode.OK);
}

只是基于 John Skeet 解释的 async/await 概念的假设。 async/await 模式使用维护状态机的延续。基本上框架应该执行指令直到同步方法结束。

当它遇到异步调用指令时,它会调用它,如果结果很容易获得,则进入下一步并进行处理。如果它在调用后没有立即得到结果,它 return 将从方法返回,让框架处理这个问题。所以在你的情况下,我认为如果你没有代码,它实际上会立即 return 。但是如果你有任何长 运行 代码,它应该 return 将工作留给后台框架线程,但结果可能会稍后返回。

如果您的 objective 是为了确保您不会阻挡前景,那么这将通过第一个控制器本身来实现。但即使在你的情况下,第二个控制器也不会阻止 UI。对于您关于这是对还是错的问题,我敢肯定,因为您可能出于某些原因会想到这种模式。

这里高手云集。如果我的解释有误,请纠正我:)

您启动后台工作并立即响应。异步模式仅在您必须以任何方式响应长 运行 任务的结果并防止阻塞调用线程的情况下使用。 即:

public bool ControllerAMethod(byte[] somedata)
{
  Task.Factory.StartNew(() =>
  {
    ControllerB.SendData(somedata);
  });
  return true;
}