Microsoft.AspNetCore.Identity UserManager GetUserAsync [英] Microsoft.AspNetCore.Identity UserManager GetUserAsync

查看:318
本文介绍了Microsoft.AspNetCore.Identity UserManager GetUserAsync的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读UserManager.cs的源代码,并且进入了以下代码段:

I've been reading the source code of UserManager.cs and I've stepped into the 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 very curious if there is a reason why the above is not like 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 you can see I've only added async/await.

*我正在与另一个ORM一起实现UserManager类.

*I'm implementing the UserManager class with another ORM.

推荐答案

由于我没有写过,所以我不确定. ;)但是我想这与return await -anti模式有关.

Since I didn't write it I cannot know for certain. ;) But I guess it's regarding the return await-anti pattern.

在GitHub上甚至还有一个问题,要求Roslyn在编译时对其进行处理.

There's even an issue for it on GitHub, where the request is that Roslyn handles it when compiling.

优化将"return await e"终止为非异步"return e"的异步方法"

此优化将提高异步方法的性能 其唯一等待出现在末尾.生成调试代码时不 嵌套在try块中时不会.

this optimization would improve the performance of an async method whose only await appears at the end. Not when producing debug code and not when nested in a try block.

引用 damien_the_unbeliever 中的出色评论,他在

To quote the excellent comment from damien_the_unbeliever, which he posted on this question

await是暂停当前方法直到另一段 代码已经完成了工作.如果您的所有方法都将在何时执行 恢复是说我完成了",那么你为什么要去所有的 努力?话虽如此,实际反模式是return await,如果 那是方法中的 only await(就在这里),不是 在try块中并带有finallyusing块(在这种情况下, 返回后还有其他代码要运行

await is a way of pausing the current method until some other piece of code has done its job. If all that your method is going to do when it's resumed is to say "I'm done" then why did you go to all of the effort? That being said, the actual anti-pattern is return await if that's the only await in the method (as it is here) and it's not within a try block with a finally or a using block (in which case there is additional code to run after return

使用await/async时,应该知道它所造成的开销.

When using await/async one should be aware of the overhead it creates.

以这两个类为例:

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();
    }
}

如果您使用 ILSpy Bar中反编译代码,则将类似于:

If you decompile the code from Bar with ILSpy will look something like 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;
    }
}

Foo看起来像这样:

public class Foo : BaseClass
{
    public Task<int> GetId()
    {
        return base.GetIdAsync();
    }
}

因此,总而言之,如果您只是要从一个Task返回值,则实际上没有理由await.相反,您应该返回Task并让调用方 await代替该Task.等待Task会扩展堆栈并创建开销,只会对性能产生负面影响.

So, to sum up, if you're simply going to return the value from one Task, there's really no reason to await it. Instead you should return the Task and let the caller await that Task instead. Awaiting the Task extends the stack and creates an overhead which only affects performance negatively.

这篇关于Microsoft.AspNetCore.Identity UserManager GetUserAsync的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆