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-patternreturn await
if that's onlyawait
in method (as here) , it's not withintry
blockfinally
orusing
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
Post a Comment