Simple long polling in ASP.NET Core SPA

Typically, ASP.NET MVC model handles requests by receiving the request, do some processing and then return the response, all within an action method. But in case of doing a long polling, we don’t have anything to return until the expected event occurs. Therefore, the long polling request needs to be able to wait for the event, without holding up the processing thread. There doesn’t seem to have a built-in capability of ASP.NET MVC to perform long polling, but with a simple setup, long polling can be done through ASP.NET MVC.

The little trick is the use of class TaskCompletionSource

Let’s take a look at the highlighted lines. WaitAsync() is invoked when we want to initiate a long polling. Task.WhenAny() will perform a blocking wait till the TaskCompletionSource has it’s result set to ‘True’ by a triggering event. Task.Delay(60000) defines a 60 seconds timeout. Therefore, the blocking will also end if the event has not occured within 60 seconds. _Message property stores the data provided by the triggering event, or null if timeout.

So MVC action to perform a long polling request looks like this:

The triggering event, when occurs, shall invoke SimpleLongPolling.Publish() to notify all long polling requests that are waiting on the same channel. Notify() of each matching long polling request will be called to set the TaskCompletionSource result to ‘True’, thus ending the blocking wait and continue execution.

MVC action to simulate an event trigger looks like this:

This is a simple implementation to demonstrate how the long polling requests can be handled by ASP.NET and it will work on a single server. To work in multiple hosts (web farm), ability to communicate among different hosts using feature like Redis Pub/Sub or some messaging bus infrastructure would be required.

Note: while there are newer technologies like SignalR using web sockets or  Web Push that facilitate real time update/notification from server, there are still occasions when simple long polling is still a reasonable way of offering real time update/notification.


Example code is available at Github.

Leave a Reply

Your email address will not be published. Required fields are marked *