我真的应该在内部方法中使用 async-await 吗?
Should I actually use async-await in inner methods?
假设我有如下 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 中,据说
If you can write it without await, then you should write it without await, and remove the async keyword from the method. A non-async method returning Task.FromResult is more efficient than an async method returning a value.
在这种情况下,Dapper 制作的数据库调用是否符合我可以在不使用异步等待且只是 return 一个 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 关键字,只是 returned Task
对象。
关于没有异步等待的第二个实现:
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 微秒。换句话说,它会在调用它 1,000,000 次后为您节省 CPU 整整一秒的时间。这些都是好消息。
坏消息是,所有这 1,000,000 次调用将导致 ObjectDisposedException
,因为 SqlConnection
将在创建 Task
后立即过早处理。
值得吗?我会说不。保持简单会在漫长的 运行.
中为您节省更多时间
假设我有如下 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 中,据说
If you can write it without await, then you should write it without await, and remove the async keyword from the method. A non-async method returning Task.FromResult is more efficient than an async method returning a value.
在这种情况下,Dapper 制作的数据库调用是否符合我可以在不使用异步等待且只是 return 一个 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 关键字,只是 returned Task
对象。
关于没有异步等待的第二个实现:
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 微秒。换句话说,它会在调用它 1,000,000 次后为您节省 CPU 整整一秒的时间。这些都是好消息。
坏消息是,所有这 1,000,000 次调用将导致 ObjectDisposedException
,因为 SqlConnection
将在创建 Task
后立即过早处理。
值得吗?我会说不。保持简单会在漫长的 运行.
中为您节省更多时间