我正在尝试找出使用异步等待通过 Entity Framework 选择数据的最佳方式。在下面的代码中,我有两个选项。
第一个使用 Task.FromResult。
第二个选项尝试使用 async await 关键字来优化代码。
1.
public Task<IEnumerable<DesignExample>> ExecuteAsync(GetAllExamplesQuery query)
{
var designExamples = _copyDataDb.DesignExamples.OrderBy(dE => dE.Order).Select(DesignExample.MapFromEntity);
return Task.FromResult(designExamples);
}
2.
public async Task<IEnumerable<DesignExample>> ExecuteAsync(GetAllExamplesQuery query)
{
var designExamples = await _copyDataDb.DesignExamples.OrderBy(dE => dE.Order).ToListAsync();
return designExamples.Select(DesignExample.MapFromEntity);
}
- 与第一个选项相比,第二个选项是否提高了整体性能?
- 第二个选项将等待对数据库的调用,但在这种情况下这真的能给我带来任何好处吗?
最佳答案
这些方法做两件不同的事情。
您的前者执行对 DbContext
的调用同步 并将结果包装在 Task
中。这意味着调用线程在调用数据库时不会将控制权交还给调用者。此方法的使用者可能不明白为什么此 ExecuteAsync
会阻塞他们的线程。
后者使用ToListAsync
进行异步 调用,释放调用线程。这意味着调用者可以同时使用线程做更多的工作,并且当查询完成执行时将恢复执行。
Does the second option increase overall performance in relation to the first?
为了知道您将不得不衡量您的代码,这主要取决于执行查询需要多长时间。请注意,使用 async-await
确实会在幕后生成状态机的开销(尽管对于代码可读性的增益来说是最小的)。请注意,您不能对同一个 DbContext 执行多个查询。
The second option will await the call to the database, but will that really give me any benefits in this scenario?
这样做的主要好处是,当查询运行时,您的线程可以自由地做更多的工作。在 ASP.NET 等环境中,这意味着 ASP.NET 线程池可以同时处理更多传入请求,这实际上取决于您要实现的目标。
在 Why does the EF 6 tutorial use asychronous calls? 中对异步数据库调用的使用进行了有趣的讨论。我想你会觉得很有趣。
关于c# - EF 选择性能 - Task.FromResult 与 ToListAsync,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25360701/