I need to implement an asynch Action in my Controller for a long running external API call.
Looking at some tutorials, I have implemented my method like this:
<
My question is, is this enough to make is truly non-block asynchronous? Do I also need to apply the await operator, and if so how should I do that?
You should use the await keyword in asynchronous MVC actions for the following reasons:
await keyword gives you a possibility to rollback changes in the case of external service failure. Otherwise this may lead to inconsistent state, because user can't replay the given async operation only, it can replay only the whole action.That is why you should not use neither async without await, nor other .NET async techniques like TPL. In this case, a custom Windows service with WCF is a preferable solution, but it greatly complicates the programming, deployment and maintenance tasks.
Of course, you can use the HostingEnvironment.RegisterObject, here is a good article. But when ASP.NET call the Stop method of your implementation of the IRegisteredObject interface (during the shutdown), you have only 30 seconds (by default) to save your data. If you have outstanding async operations, you should abort them, mark them failed and retry them after restart or send failure notifications to users. And if your storage will also be unavailable at this time, then say bye-bye to your results (including failed results).
You can also use persistent queues, reliable fetching and dedicated workers that listen these queues inside ASP.NET application. This can protect you even from worker process termination. Moreover, there are a lot of project, like Resque, Sidekiq, Pyres, etc., but they are for other languages.
For .NET, give a try to HangFire – it is under development yet, but much stable and than initial implementation of such systems, and has many different features.