什么被认为是最佳(或更好)的做法,具有默认状态和原因,以及它们的真正好处是什么?
例如,如果我们在控制器中有 Get 方法,那么它应该是:
public virtual IActionResult Get(int page = 1, int pageSize = 100)
{
var q = repository.Query().AsNoTracking().ProjectTo<UserViewModel>();
q = q.Skip((page - 1) * pageSize).Take(pageSize);
return new OkObjectResult(q);
}
或
public virtual async Task<IActionResult> Get(int page = 1, int pageSize = 100)
{
var q = repository.Query().AsNoTracking().ProjectTo<UserViewModel>();
q = q.Skip((page - 1) * pageSize).Take(pageSize);
return new OkObjectResult(await q.ToListAsync());
}
如果首选 async ,这段代码是否适合它并且足够了?
存储库中的 Query()也只是为了
public virtual IQueryable<User> Query() { return context.Set<User>().AsQueryable(); }
我在这里发现 async 实际上更慢了:
https://github.com/aspnet/EntityFramework/issues/5816
该错误显然是固定的,但我不知道最新版本中的性能比较是什么。
答案 0 :(得分:3)
async/await
优于常规同步代码的好处,当您的服务器负载足够大以至于释放线程池上的线程有所不同时,这是最大的。在此之前,上下文跟踪和切换的开销很容易大于释放线程的性能提升。
我倾向于使用异步API而不是同步,主要是因为我已经进入了一些项目,其中高负载和同步代码是一个足够高的问题,有人认为是时候重构并转移到{{1每次都是痛苦的。仅公开async
API会变得越来越普遍(例如,Azure SDK有许多async
个动作没有同步对应物),这意味着您可能如果您最终使用这样的API,则稍后执行此类重写。
但如果您想要考虑性能,那么您需要在实际负载下分析您的应用程序,并了解哪种方法效果最佳。
附录:
引入更多async
/ async
开销非常容易。我喜欢使用的一个很好的经验法则是考虑可以返回await
或Task
的三种类型的方法,并分别遵循以下模式中的一种:
实际上是同步的方法(但返回Task<T>
或Task
,例如为了允许使用异步变量进行重载):返回Task<T>
。
Task.FromResult
转发到异步方法但不做其他任何事情的方法:只返回public Task<string> ActuallySynchronousGetter()
{
return Task.FromResult("foo");
}
,不需要Task
。
await
实际的异步方法,它们都执行异步操作(通常是I / O),然后使用该异步操作的结果:这是您实际需要// note: no async/await, just Task<T>
public Task<string> ForwardingGetter()
{
return SomeOtherGetter(); // also with return type Task<string>
}
和async
个关键字。
await
您的代码似乎属于第三种情况 - 您需要public async Task<string> GetStringAsynchronously()
{
var str = await SomeOtherGetter();
return str.Replace("foo", "bar"); // note: we need the actual string here
}
的结果才能将其传递给.ToListAsync()
构造函数。我可能已将整个事情写成一个陈述,但这主要是一个品味问题:
OkObjectResult
Stephen Cleary详尽而深入地介绍了var data = await repository.Query()
.AsNoTracking()
.ProjectTo<UserViewModel>()
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
return new OkObjectResult(data);
和async
如何运作,以及您应该(而且不应该)如何使用它。