I have a C# ASP.Net (non MVC) project that uses Ajax Comet long-polling. A web page makes a HTTP call to an endpoint handled by a class implementing IHttpAsyncHandler.
If there is nothing to report (within n seconds) to the web page, an empty HTTP response is sent, and the webpage re-calls. If there is something to send, and update is sent, and the webpage processes and re-calls. This is pretty standard push technology, and works very well.
Now I am trying to add API endpoints, using WebAPI2, non-MVC. I have synchronous controllers working, based on the ApiController class.
I would like to set up push technology for the API calls, so that API users do not have to poll for updates.
Similar to the method above, the API endpoint call is received, and the context is stored. If a timeout expires, the call is returned empty, and the caller is expected to call again. If data updates within the timeout, the data is returned to the caller, and the caller is then expected to call again and wait for more updates.
The problem is that there seems to be no asynchronous version of ApiController. The aim is to free the thread that is handling the API call, to return it to the pool, and then when there is data available, or the timeout expires, a worker thread is used to return the response.
How can I set up an ApiController so that the thread processing the call is freed, the call context is stored, and I can send a response to the call at a later point in time?
You can use async/await to achieve what you want i.e.:
[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;
}
In this example the Web API method is declared as async
and in its body await
operator was used to return a thread to a pool.
I assumed that in order to implement Comet you uses some kind of events. As far as I remember many years ago I used ManualResetEvent
to do so. However, it can be anything else.
What is important is that WaitForEvent
method should return something awaitable. In other words ManualResetEvent
or other wait handle should be wrapped in a task. You can do that with AsyncFactory.FromWaitHandle method.
It is also worth reading this discussion about asyn/await in the context of Web API.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With