什么被认为是默认状态的最佳(或更好)实践,为什么,以及两者的真正好处是什么?
例如,如果我们在 Controller 中有 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,这段代码是否适合它?
Repository 中的 Query() 也很简单
public virtual IQueryable<User> Query() { return context.Set<User>().AsQueryable(); }
我在这里发现 async 实际上更慢:
https://github.com/aspnet/EntityFramework/issues/5816
那个bug貌似修复了,但是不知道最新版本的性能对比如何。
最佳答案
async/await
的好处当您的服务器承受足够大的负载以至于释放线程池中的线程会产生影响时,常规的同步代码是最大的。在此之前,上下文跟踪和切换的开销很容易大于释放线程带来的性能提升。
我倾向于使用异步 API 而不是同步,主要是因为我参与过一些项目,其中高负载和同步代码是一个足够高的问题,以至于有人决定是时候重构并转移到 async
了。 ,每次都很痛苦。只公开 async
也变得越来越普遍API:s(例如,Azure SDK 有许多没有同步对应项的 async
操作),这意味着您可能必须稍后执行这样的重写,如果您结束开始使用这样的 API。
但如果性能是您唯一要考虑的因素,您需要在实际负载下分析您的应用程序,看看哪种方法最有效。
附录:
很容易介绍更多 async
/await
不必要的开销。我喜欢使用的一个很好的经验法则是考虑三种可以返回 Task
的方法。或 Task<T>
, 并分别遵循以下模式之一:
实际上是同步的方法(但返回
Task
或Task<T>
,例如为了允许使用异步变量重载):返回Task.FromResult
.public Task<string> ActuallySynchronousGetter() { return Task.FromResult("foo"); }
转发给异步方法但不做任何其他事情的方法:只返回
Task
, 不需要await
// note: no async/await, just Task<T> public Task<string> ForwardingGetter() { return SomeOtherGetter(); // also with return type Task<string> }
实际的异步方法,它们都执行一些异步操作(通常是 I/O),然后使用该异步操作的结果:这是您真正需要
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
构造函数。我可能会把整个事情写成一个声明,但这主要是一个品味问题:
var data = await repository.Query()
.AsNoTracking()
.ProjectTo<UserViewModel>()
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
return new OkObjectResult(data);
Stephen Cleary关于如何 async
写了很多深入的文章和 await
工作原理,以及您应该(和不应该)使用它的方式。
关于c# - .Net Core Web API 方法是否与 EF Core 查询异步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44904803/