David C
David C

Reputation: 2796

Using Async controller action to call existing synchronous method

I've not dealt much with Async/threads/Tasks other than some web services.

I'm using MVC4. I have existing code which takes some time to run. It is using an existing method in the service layer, which uses various other the areas in further layers.

Essentially I was hoping to be able to make an ASync call from the Asynccontroller to that method. However it appears that I would need to change/create another method to implement all the Task & await keywords, quite a hefty job altering all the way down the chain.

Is it possible to call/'fire' a synchronous method in this manner?

I want the long process (creating some documents in the background) to continue running even if the user closes their browser. However if the user still has the browser open then I would like to return a notification to them.

Is there a better way to fire a background task to execute from the MVC Application?

Upvotes: 2

Views: 1203

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 456322

I think you're trying to use async for something it cannot do. As I describe on my blog, async does not change the HTTP protocol.

Is it possible to call/'fire' a synchronous method in this manner?

Sort of. You can use Task.Run if you have CPU-bound work that you want to move off the UI thread in a desktop/mobile application. But there is no point in doing that in an ASP.NET MVC application.

I want the long process (creating some documents in the background) to continue running even if the user closes their browser. However if the user still has the browser open then I would like to return a notification to them.

The problem with this is that you'd be returning early from an ASP.NET request, and (as I describe on my blog), that's quite dangerous.

A proper solution would be to queue the work in a reliable queue (e.g., Azure queue or MSMQ), have an independent backend for processing (e.g., Azure worker role / web job or Win32 service), and use something like SignalR for notification.

As soon as you attempt to do work in an ASP.NET process without a request context, then you run into the danger that your process may exit without completing the work. If you are OK with this, then you can use the BackgroundTaskManager type from my blog above to minimize the chance of that happening (but keep in mind: it can still happen).

Upvotes: 4

Related Questions