Should I use await with async Action method?

前端 未结 4 1689
春和景丽
春和景丽 2020-12-11 06:36

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:

<
4条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-11 07:00

    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:

    1. If your action changes the state of your application (updates database, etc.), then 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.
    2. Hosting environment (IIS) can cause app domain to unload due to different reasons. When it happens, your application could never get the result of an asynchronous operation. In a regular request processing case, ASP.NET waits for each operation to complete. If some requests are taking too long to complete (and exceed the shutdown timeout), ASP.NET aborts them and sends the failure response.

    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.

提交回复
热议问题