asp.net - Starting and Forgetting an Async task in MVC Action -


i have standard, non-async action like:

[httppost] public jsonresult startgeneratepdf(int id) {     pdfgenerator.current.generateasync(id);     return json(null); } 

the idea being know pdf generation take long time, start task , return, not caring result of async operation.

in default asp.net mvc 4 app gives me nice exception:

system.invalidoperationexception: asynchronous operation cannot started @ time. asynchronous operations may started within asynchronous handler or module or during events in page lifecycle. if exception occurred while executing page, ensure page marked <%@ page async="true" %>.

which kinds of irrelevant scenario. looking can set flag false prevent exception:

<appsettings>     <!-- allows throwaway async operations mvc controller actions -->     <add key="aspnet:allowasyncduringsyncstages" value="true" /> </appsettings> 

https://stackoverflow.com/a/15230973/176877
http://msdn.microsoft.com/en-us/library/hh975440.aspx

but question is, there harm kicking off async operation , forgetting synchronous mvc controller action? can find recommends making controller async, isn't i'm looking - there no point since should return immediately.

relax, microsoft says (http://msdn.microsoft.com/en-us/library/system.web.httpcontext.allowasyncduringsyncstages.aspx):

this behavior meant safety net let know on if you're writing async code doesn't fit expected patterns , might have negative side effects.

just remember few simple rules:

  • never await inside (async or not) void events (as return immediately). webforms page events support simple awaits inside them - registerasynctask still highly preferred approach.

  • don't await on async void methods (as return immediately).

  • don't wait synchronously in gui or request thread (.wait(), .result(), .waitall(), waitany()) on async methods don't have .configureawait(false) on root await inside them, or root task not started .run(), or don't have taskscheduler.default explicitly specified (as gui or request deadlock).

  • use .configureawait(false) or task.run or explicitly specify taskscheduler.default every background process, , in every library method, not need continue on synchronization context - think of "calling thread", know not 1 (and not on same one), , may not exist anymore (if request ended). alone avoids common async/await errors, , increases performance well.

microsoft assumed forgot wait on task...

update: stephen (pun not intended) stated in answer, there inherit hidden danger forms of fire-and-forget when working application pools, not solely specific async/await, tasks, threadpool, , other such methods - not guaranteed finish once request ends (app pool may recycle @ time number of reasons).

you may care or not (if it's not business-critical in op's particular case), should aware of it.


Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

c++ - qgraphicsview horizontal scrolling always has a vertical delta -