创建一个立即返回OK的异步控制器

时间:2015-02-02 11:42:18

标签: c# asp.net .net asynchronous async-await

我试图与webapi结合使用新的异步/等待功能。

我想做的是以下内容:

  • 我在某个端点上的控制器(A)上收到(POST)请求。
  • 这个控制器什么都不做,只是将这个请求发送到另一个端点上的第二个控制器(B)(不要问我为什么 - 只是一个思想实验)。
  • 让我们说B做一些长时间的工作(从某处检索数据)并将结果存储在数据库中。

我不想等待来自B的工作,然后才能将OK消息返回给发送给A的请求。我希望能够在工作时尽快打电话给A并获得OK仍在B上完成。

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

感谢你给我的任何指示。

4 个答案:

答案 0 :(得分:4)

你想要的是触发"火和忘记"你的电话中的语义。

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

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

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

示例如下:

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

答案 1 :(得分:1)

您可能希望使用response code of 202 (accepted)响应呼叫者,以向客户端指示正在进行其他一些处理。 然后,如果您的客户需要额外的反馈,它可以进行长时间的轮询,或者您可以实现websocket等。

答案 2 :(得分:1)

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

当遇到异步调用指令时,它会调用它,如果结果随时可用,则转到后续步骤并进行处理。如果它在调用之后没有立即得到结果,它将从方法返回,留下这个由框架处理。所以在你的情况下,我认为如果你没有代码,它会立即返回。但是如果你有任何长时间运行的代码,它应该返回将作业留给后台框架线程,但结果可能会在稍后返回。

如果您的目标是确保不阻挡前景,那么这将通过第一个控制器本身来实现。但即使在你的情况下,第二个控制器也不会阻止UI。关于这是对还是错的问题,我确信,因为你可能有一些理由考虑这种模式。

这里有很多专家。如果我的解释错了,请纠正我,请:)

答案 3 :(得分:1)

您开始后台工作并立即回复。仅当您必须以任何方式响应长时间运行的任务的结果并防止阻塞调用线程时,才使用异步模式。 即:

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