asp.net - Microsoft.AspNetCore.Identity UserManager GetUserAsync -


i've been reading source code of usermanager.cs , i've stepped following block:

        public virtual task<tuser> getuserasync(claimsprincipal principal)     {         if (principal == null)         {             throw new argumentnullexception(nameof(principal));         }         var id = getuserid(principal);         return id == null ? task.fromresult<tuser>(null) : findbyidasync(id);     } 

i've been curious if there reason why above not this:

        public virtual async task<tuser> getuserasync(claimsprincipal principal)     {         if (principal == null)         {             throw new argumentnullexception(nameof(principal));         }         var id = getuserid(principal);         return id == null ? await task.fromresult<tuser>(null) : await findbyidasync(id);     } 

as can see i've added async/await.

*i'm implementing usermanager class orm.

since didn't write cannot know certain. ;) guess it's regarding return await-anti pattern.

there's issue on github, request roslyn handles when compiling.

optimize async method ends "return await e" non-async "return e"

this optimization improve performance of async method await appears @ end. not when producing debug code , not when nested in try block.

to quote excellent comment damien_the_unbeliever, posted on this question

await way of pausing current method until other piece of code has done job. if method going when it's resumed "i'm done" why did go of effort? being said, actual anti-pattern return await if that's only await in method (as here) , it's not within try block finally or using block (in case there additional code run after return

when using await/async 1 should aware of overhead creates.

take these 2 classes example:

public class baseclass {     public async task<int> getidasync()     {         return await task.run(() => 100);     } }  public class foo : baseclass {     public task<int> getid()     {         return getidasync();     } }   public class bar : baseclass {     public async task<int> getid()     {         return await getidasync();     } } 

if decompile code bar ilspy this:

public class bar : baseclass {     [debuggerstepthrough, asyncstatemachine(typeof(bar.<getid>d__0))]     public task<int> getid()     {         bar.<getid>d__0 <getid>d__ = new bar.<getid>d__0();         <getid>d__.<>4__this = this;         <getid>d__.<>t__builder = asynctaskmethodbuilder<int>.create();         <getid>d__.<>1__state = -1;         asynctaskmethodbuilder<int> <>t__builder = <getid>d__.<>t__builder;         <>t__builder.start<bar.<getid>d__0>(ref <getid>d__);         return <getid>d__.<>t__builder.task;     } } 

while foo looks this:

public class foo : baseclass {     public task<int> getid()     {         return base.getidasync();     } } 

so, sum up, if you're going return value 1 task, there's no reason await it. instead should return task , let caller await task instead. awaiting task extends stack , creates overhead affects performance negatively.


Comments

Popular posts from this blog

Spring Boot + JPA + Hibernate: Unable to locate persister -

go - Golang: panic: runtime error: invalid memory address or nil pointer dereference using bufio.Scanner -

c - double free or corruption (fasttop) -