如何通过 WebAPI2 执行 C# Ajax Comet?

How to do C# Ajax Comet via WebAPI2?

我有一个使用 Ajax Comet 长轮询的 C# ASP.Net(非 MVC)项目。网页对由 class 实现 IHttpAsyncHandler 处理的端点进行 HTTP 调用。

如果(n秒内)网页没有什么可报告的,则发送一个空的HTTP响应,网页重新调用。如果有东西要发送,则发送更新,网页处理并重新调用。这是非常标准的推送技术,效果很好。

现在我正在尝试添加 API 个端点,使用 WebAPI2,非 MVC。我有同步控制器,基于 ApiController class。

我想为 API 调用设置推送技术,这样 API 用户就不必轮询更新。

与上面的方法类似,接收到API端点调用,并存储上下文。如果超时过期,则调用 return 为空,调用者应再次调用。如果数据在超时内更新,数据将 return 发送给调用者,然后调用者将再次调用并等待更多更新。

问题是好像没有ApiController的异步版本。目的是释放正在处理 API 调用的线程,将其 return 放入池中,然后当有可用数据或超时到期时,工作线程用于 return 响应。

如何设置 ApiController 以便释放处理调用的线程,存储调用上下文,并且我可以在稍后的某个时间点发送对调用的响应?

您可以使用 async/await 来实现您想要的,即:

[HttpPost]
public async Task<HttpResponseMessage> LongRunningOperation([FromBody]Input obj)
{
    // Do what ever you need with input data        

    await WaitForEvent();        

    // Do what ever you need to return a response

    return someResponse;
}

在此示例中,Web API 方法被声明为 async 并且在其主体中 await 运算符用于 return 池中的线程。

我假设您使用某种事件来实现 Comet。据我记得很多年前我使用 ManualResetEvent 来这样做。但是,它可以是任何其他内容。

重要的是 WaitForEvent 方法应该 return 等待的东西。换句话说,ManualResetEvent 或其他等待句柄应该包含在任务中。你可以用 AsyncFactory.FromWaitHandle 方法做到这一点。

在 Web API 的上下文中,关于 asyn/await 的这篇 discussion 也值得一读。