Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run task on background but return response to client in ASP MVC web application

I'm trying to implement a functionality where there is a stored procedure on SQL Server that has to be called from ASP MVC application and processed on the background (it might take long since it calls another stored procedure remotely to process an excel file stored on a server). But the response of the last HTTP request should be returned back to client so the UI will not be hanging waiting for processing.

I have tried so many different ways but UI is still not responding right away.

I tried BackgroundWorker but it's not allowing the main thread to response back to client until its done processing, also I tried:

Thread.QueueUserWorkItem(delegate { //method which performs stored procedure calls//
}); 

It still not returning response and HttpContext.Current not available in background thread.

Maybe there is a way to start background processing, pause it for letting main thread to return response to browser and then resume background thread to make all processing with stored procedure calls?

Am I missing something?

Could someone please give an idea how I can solve this problem? Would be much appreciated.

like image 555
Paul Avatar asked Jul 18 '14 15:07

Paul


Video Answer


2 Answers

What I ended up with and it works fine in my case. I'm not sure about efficiency, but it perfectly works. So, the code which makes calls to a stored procedure I put on a separate thread, so that the main thread is finished while the processing off background calls is happening on a separate thread and finishes successfully after some period of time. At the same time UI is available so user can make another request which will also be processed the same way. I tested three requests. One after another overlapping, meaning that while first request was being processed on the background I submitted another one and yet another one. UI was responding immediately and all the work was done.

// ...main thread is working here
    //put a call to stored procedure on a separate thread
    Thread t = new Thread(()=> {
       //call stored procedure which will run longer time since it calls another remote stored procedure and
       //waits until it's done processing
    });
    t.Start();

   // ...main thread continue to work here and finishes the request so it looks for user as the response is coming right away, all other stuff is being processed on that new thread so user even doesn't suspect
like image 170
Paul Avatar answered Oct 13 '22 00:10

Paul


I shall quote Stephan Clearys great article:

When you use async on the server side (e.g., with ApiController), then you can treat each web request as an asynchronous operation. But when you yield, you only yield to the web server thread pool, not to the client. HTTP only allows a single response, so the response can only be sent when the request is fully complete.

Basically, this doesn't adhere to the HTTP protocol, where each request has only one response.

This can be achieved using multiple calls to the ASP.NET service, where a request returns a unique ID immediately, which the client can query multiple times for progress. You may look into SignalR for help with such an implementation:

What is SignalR and "real-time web" functionality? It's the ability to have your server-side code push content to the connected clients as it happens, in real-time.

like image 41
Yuval Itzchakov Avatar answered Oct 12 '22 22:10

Yuval Itzchakov