C# 我应该在内部方法中使用async await吗?

C# 我应该在内部方法中使用async await吗?,c#,async-await,dapper,C#,Async Await,Dapper,假设我有3种方法,如下所示: 公共异步任务CalculateDataint索引,int信任级别,字符串类型 { var x=等待计算的核心指数,类型; 返回ComplexProcessx,信任级别; } 公共异步任务CalculateBaseCoreint索引,字符串类型 { 变量conn_字符串=。。。; var-sql=。。。; var param=new{Index=Index,Type=Type}; 使用var conn=new SqlConnectionconn\u字符串 { var

假设我有3种方法,如下所示:

公共异步任务CalculateDataint索引,int信任级别,字符串类型 { var x=等待计算的核心指数,类型; 返回ComplexProcessx,信任级别; } 公共异步任务CalculateBaseCoreint索引,字符串类型 { 变量conn_字符串=。。。; var-sql=。。。; var param=new{Index=Index,Type=Type}; 使用var conn=new SqlConnectionconn\u字符串 { var db_output=await conn.ExecuteScalarAsyncsql,param:param; 返回db_输出; } } public int calculateBaseCoreint索引,int信任级别 { //省略 } 如您所见,其中两个使用异步等待

斯蒂芬·克利里的书中说

如果可以在不等待的情况下编写,那么应该在不等待的情况下编写,并从方法中删除async关键字。返回Task.FromResult的非异步方法比返回值的异步方法更有效

在这种情况下,一个简洁的数据库调用是否符合我编写的方法的条件,而无需异步等待,只需返回一个任务对象?如果我改成这样,我会在性能或其他方面得到任何好处吗

公共异步任务CalculateDataint索引,int信任级别,字符串类型 { var x=等待计算的核心指数,类型; 返回ComplexProcessx,信任级别; } 公共任务CalculateBaseCoreint索引,字符串类型 { 变量conn_字符串=。。。; var-sql=。。。; var param=new{Index=Index,Type=Type}; 使用var conn=new SqlConnectionconn\u字符串 { var db_output_task=conn.ExecuteScalarAsyncsql,param:param; 返回数据库输出任务; } } public int calculateBaseCoreint索引,int信任级别 { //省略 }
参见第二个示例中的tht,我省略了CalculateBaseCore上的async await关键字,只返回了Task对象。

关于第二个没有async await的实现:

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;
    }
}
…将使每次调用的性能提高约1微秒。换句话说,在调用1000000次后,它将为您节省整整一秒钟的CPU时间。这些都是好消息

坏消息是,所有这些1000000次调用都将导致ObjectDisposedException,因为SqlConnection将在创建任务后立即被过早地释放


值得吗?我会说不。从长远来看,保持简单会节省更多时间。

关于第二个不使用async Wait的实现:

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;
    }
}
…将使每次调用的性能提高约1微秒。换句话说,在调用1000000次后,它将为您节省整整一秒钟的CPU时间。这些都是好消息

坏消息是,所有这些1000000次调用都将导致ObjectDisposedException,因为SqlConnection将在创建任务后立即被过早地释放


值得吗?我会说不。从长远来看,保持简单会节省更多的时间。

这里有一个建议。查找不包含async/await关键字的标题。答案是肯定的,您可以省略async,只返回任务,就像您在Dapper示例中一样。如果我执行X,那么我将获得性能胜利的问题只能通过执行X和不执行X,并比较以用户为中心、仔细测量的性能指标来确定回答。唯一能做到这一点的人是你;如果你有两匹马,你想知道哪匹马跑得更快,那么在互联网上询问从未见过你的马的陌生人猜一猜并不能代替简单的赛马@TomTom:我们没有创造价值任务,因为它们更快。我们创建它们是因为在任务可能已经完成的场景中,它们降低了收集压力。此外,正如西奥多的回答所指出的,问题是这些选择中哪一个更快?需要比较的两个工作流都是正确的,并且执行相同的操作。先集中精力!在这几年中,我改变了我的立场,现在除了最琐碎的案件外,我也改变了我的立场。我现在要更新旧的帖子。这里有一个。查找不包含async/await关键字的标题。答案是肯定的,您可以省略async,只返回任务,就像您在Dapper示例中一样。如果我执行X,那么我将获得性能胜利的问题只能通过执行X和不执行X,并比较以用户为中心、仔细测量的性能指标来确定回答。唯一能做到这一点的人是你;如果你有两匹马,你想知道哪匹马跑得更快,那么在互联网上询问从未见过你的马的陌生人猜一猜并不能代替简单的赛马@TomTom:我们没有创造价值任务,因为它们更快。我们创建它们是因为在任务可能已经完成的场景中,它们降低了收集压力。此外,正如西奥多的回答所指出的,问题是这些选择中哪一个更快?要求要比较的两个工作流都是
纠正错误并做同样的事情。先集中精力!在这几年中,我改变了我的立场,现在除了最琐碎的案件外,我也改变了我的立场。我现在就要更新旧的帖子了;请始终记住,工作流中必须有一个等待位置,工作流的其余部分在前一部分完成之前不得继续。如果要求工作流结束时的清理代码在工作流开始时完成后才能执行,则需要等待;请始终记住,工作流中必须有一个等待位置,工作流的其余部分在前一部分完成之前不得继续。如果要求工作流末尾的清理代码在工作流开始完成之前不执行,则需要等待。