c# - 在 ASP.NET 中正确使用 Task.Run 和 Task.WaitAll 进行 EF 调用
问题描述
精简版:
任何人都可以确认,带有 EF 调用的非异步子功能上的 Task.Run/Task.WaitAll 对 ASP.NET 应用程序有什么好处吗?
长版:
我们有一个 Asp.Net WebApi 服务,它的方法可以进行多个 DB 调用(全部使用 EntityFramework)来收集一组数据,这些数据全部返回到单个响应对象中。我们将其分解为一系列子功能,并希望它们并行运行(注意:这些都没有使用任何异步调用)。
为了实现某种形式的并行编码,我们使用 Task.Run 调用每个函数,然后是 Task.WaitAll:
public ResponseObject PopulateResponseObject(int id)
{
var response = new ResponseObject();
Task<DataSetA> dataSetATask = Task.Run(() => getDataSetA(id));
Task<DataSetB> dataSetBTask = Task.Run(() => getDataSetB(id));
Task.WaitAll(dataSetATask, dataSetBTask);
response.SetA = dataSetATask.Result;
response.SetB = dataSetBTask.Result;
return response;
}
从我一直在阅读的内容来看,Task.Run 可能不会在 Asp.Net 应用程序中获得太多收益,而我们在这里所拥有的可能只会导致不必要的线程池开销。
我们是否在浪费时间以这种方式编写代码?
更新:我们熟悉 EF 具有异步版本的事实,但需要修改大量代码。我们希望保持这些功能不变。
解决方案
使用 Task.Run 至少可以让您并行运行两个查询,所以是的,可以获得改进(与您按顺序运行查询的完全同步版本相比)。
但是,收益仅限于您在线程池中拥有的线程数(最终受限于您的服务器容量)。通过使用 EF 异步 api,您将获得更多收益,因为这将允许执行许多查询,而无需为每个查询占用一个线程。
但这是开始使用异步代码的合理策略。完成此操作后,您可以返回并慢慢将查询转换为使用异步 api。
推荐阅读
- android - 让 Java2OP 识别新的桥文件
- c# - 传递所选项目时出现绑定上下文错误
- angular - Angular,错误类型错误:items.filter 不是函数
- typescript - 打字稿源文件中带有 ts-jest 断点的 vscode-jest
- java - java中的惰性日志消息评估
- ruby - Ruby 中 BasicObject 的单例类的单例类
- javascript - 通过 Direct Line 在可折叠窗口中嵌入 Microsoft Bot
- scala - 使用 Scala 以优化的方式将 NA 值替换为“0”
- javascript - 在 Storybook 和 Angular 中加载 scss 文件:预期 1 个选择器或规则,是“var content = requi”
- r - 从单个字符串中提取两年