c# - Unnecessary async/await when await is last? -


i've been dealing quite lot async await lately (read every possible article including stephen's , jon's last 2 chapters) , have come conclusion , don't know if it's 100% correct. - hence question .

since async allows word await present , i'll leave async aside.

afaiu , await continuation . instead of writing functional (continuational) code , write synchronous code. ( refer callback'able code)

so when compiler reaches await - splits code 2 sections , registers second part executed after first part done ( i don't know why word callback isn't used - done). ( meanwhile working - thread doing other things).

but looking @ code :

public async  task processasync()         {            task<string> worktask = simulatework();            string st= await worktask;            //do st         }   public    task <string> simulatework()         {             return ...         } 

when thread reaches await worktask; split method 2 sections . after simulatework finished - continuation of method : aka : //do st - executed.

all ok

but if method :

public async  task processasync()         {            task<string> worktask = simulatework();            await worktask; //i don't care result , , don't have further commands          } 

here - don't need continuation , meaning - don't need await split method means - don't need async /await here @ ! , still have same results/behaviour !

so :

   public void processasync()             {                simulatework();             } 

question:

  • was 100% correct diagnostics ?

so, think await below redundant, question's title implies:

public async task processasync() {     task<string> worktask = simulatework();     await worktask; //i don't care result , , don't have further  } 

first of all, assume under "when await last" mean "when await await". it's got that, because otherwise following not compile:

public async task processasync() {     await task.delay(1000);     task<string> worktask = simulatework();     return worktask;  } 

now, if it's only await, can indeed optimize this:

public task processasync() {     task<string> worktask = simulatework();     return worktask;  } 

however, give different exception propagation behavior, may have unexpected side effects. thing is, exceptions may thrown on caller's stack, depending on how simulatework internally implemented. posted detailed explanation of behavior. never happens async task/task<> methods, exception stored inside returned task object. still may happen async void method, that's different story.

so, if caller code ready such differences in exception propagation, may idea skip async/await wherever can , return task instead.

another matter if want issue fire-and-forget call. usually, still want track status of fired task somehow, @ least reason of handling task exceptions. not imagine case not care if task never completes, if logging.

so, fire-and-forget use helper async void method stores pending task somewhere later observation, e.g.:

readonly object _synclock = new object(); readonly hashset<task> _pendingtasks = new hashset<task>();  async void queuetaskasync(task task) {     // keep failed/cancelled tasks in list     // observed outside     lock (_synclock)         _pendingtasks.add(task);      try     {         await task;     }     catch     {         // not task's exception?         if (!task.iscanceled && !task.isfaulted)             throw; // re-throw          // swallow, not remove faulted/cancelled task _pendingtasks          // error observed later, when process _pendingtasks,         // e.g.: await task.whenall(_pendingtasks.toarray())         return;     }      // remove completed task list     lock (_synclock)         _pendingtasks.remove(task); } 

you'd call this:

public task processasync() {     queuetaskasync(simulatework()); } 

the goal throw fatal exceptions (e.g., out-of-memory) on current thread's synchronization context, while task result/error processing deferred until appropriate.

there's been interesting discussion of using tasks fire-and-forget here.


Comments

Popular posts from this blog

toolbar - How to add link to user registration inside toobar in admin joomla 3 custom component -

linux - disk space limitation when creating war file -