我一直在阅读UserManager.cs的源代码,并且我已经进入了以下块:
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);
}
如果上述原因不是这样的话,我一直非常好奇:
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);
}
如您所见,我只添加了async / await。
*我正在用另一个ORM实现UserManager类。
答案 0 :(得分:4)
由于我没有写它,我无法确定。 ;)但我想它是关于return await
- 反模式。
在GitHub上甚至存在问题,其中请求是Roslyn在编译时处理它。
Optimize an async method that ends "return await e" to be non-async "return e"
上发布的this question的优秀评论此优化将提高异步方法的性能 他们唯一的等待出现在最后。不是在生成调试代码时 不是嵌套在try块中。
await
是一种暂停当前方法直到其他方式的方法 代码完成了它的工作。如果你的方法将要做的所有 它的恢复就是说&#34;我已经完成了#34;那么你为什么要去所有的 努力?话虽这么说,实际的反模式是return await
if 这个方法中只有await
(就像在这里一样)并且它不是 在具有try
或finally
块的using
块内(在这种情况下) 返回后还有其他代码可以运行
使用await/async
时,应该知道它产生的开销。
以这两个类为例:
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
反编译代码,则会显示如下内容:
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
返回值,那么{I}真的没有理由await
。相反,您应该返回Task
并让来电者 await
代替Task
。等待Task
扩展堆栈并创建一个仅对性能产生负面影响的开销。