我试图弄清楚使用异步等待通过实体框架选择数据的最佳方法是什么。在下面的代码中,我有两个选项。
第一个使用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);
}
答案 0 :(得分:12)
这些方法做了两件不同的事情。
您的前者同时调用DbContext
同步,并将结果包装在Task
中。这意味着调用线程将不在调用数据库时将控制权返回给调用者。此方法的消费者可能无法理解为什么此ExecuteAsync
阻止了他们的主题。
后者使用ToListAsync
进行异步调用,其中释放调用线程。这意味着调用者可以在此期间对该线程执行更多操作,并且在查询完成执行时将继续执行。
第二个选项是否会提高与...相关的整体效果 第一λ
为了知道您必须测量代码,这主要取决于执行查询所需的时间。请注意,使用async-await
确实会产生开销(尽管对于代码可读性的增益而言是最小的)生成封面后的状态机。请注意,您无法对同一个DbContext执行多个查询。
第二个选项将等待对数据库的调用,但是会这样 在这种情况下真的能给我带来任何好处吗?
这样做的主要好处是,当查询运行时,您的线程可以自由地完成更多工作。在像ASP.NET这样的环境中,这意味着ASP.NET ThreadPool可以在此期间自由处理更多的传入请求,这实际上取决于你想要实现的目标。
有一个关于在Why does the EF 6 tutorial use asychronous calls?中使用异步数据库调用的有趣讨论,我认为你会感兴趣。