【发布时间】:2020-04-06 19:25:38
【问题描述】:
假设我有以下 3 种方法:
public async Task<int> CalculateData(int index, int trustLevel, string type)
{
var x = await CalculateBaseScore(index, type);
return ComplexProcess(x, trustLevel);
}
public async Task<int> CalculateBaseScore(int index, string type)
{
var conn_string = "...";
var sql = "...";
var param = new { Index = index, Type = type };
using (var conn = new SqlConnection(conn_string))
{
var db_output = await conn.ExecuteScalarAsync<int>(sql, param: param);
return db_output;
}
}
public int CalculateBaseScore(int index, int trustLevel)
{
//Omitted
}
如您所见,其中 2 个使用 async-await。
在 Stephen Cleary 的 introduction to async-await 中,据说
如果你可以在没有 await 的情况下编写它,那么你应该在没有 await 的情况下编写它,并从方法中删除 async 关键字。返回 Task.FromResult 的非异步方法比返回值的异步方法更有效。
在这种情况下,Dapper 制造的数据库调用是否符合我可以在不使用 async-await 的情况下编写并简单地返回 Task<int> 对象的方法?如果我改成这个,我会在性能或其他方面获得什么好处吗?
public async Task<int> CalculateData(int index, int trustLevel, string type)
{
var x = await CalculateBaseScore(index, type);
return ComplexProcess(x, trustLevel);
}
public Task<int> CalculateBaseScore(int index, string type)
{
var conn_string = "...";
var sql = "...";
var param = new { Index = index, Type = type };
using (var conn = new SqlConnection(conn_string))
{
var db_output_task = conn.ExecuteScalarAsync<int>(sql, param: param);
return db_output_task;
}
}
public int CalculateBaseScore(int index, int trustLevel)
{
//Omitted
}
参见第二个示例,我省略了 CalculateBaseScore 上的 async-await 关键字,只返回了 Task 对象。
【问题讨论】:
-
这是helpful link。查找标题“删除 async/await 关键字”。答案是肯定的,您可以省略
async并像在 Dapper 示例中一样返回任务。 -
只有通过做 X 和不做 X,并比较一个以用户为中心、仔细衡量的性能指标,才能明确回答“如果我做 X,我会获得性能上的胜利”这个问题。唯一能做到这一点的人就是你;如果您有两匹马,并且想知道哪匹马跑得更快,请在互联网上让从未见过您的马匹的陌生人猜一猜并不能代替简单的赛马!
-
@TomTom:我们没有创造价值任务,因为它们更快。我们创建它们是因为它们在任务可能已经完成的情况下降低了收集压力。
-
另外,正如 Theodor 的回答所指出的,“这些选择中哪一个更快?”要求被比较的两个工作流程都正确并且做同样的事情。首先集中精力!
-
这几年我改变了我的立场,现在我recommend against eliding
async/await除了在最微不足道的情况下。我现在将更新旧帖子。
标签: c# async-await dapper