【发布时间】:2021-04-05 02:27:03
【问题描述】:
我知道我们应该在访问数据库时使用异步和等待,因为处理这个请求需要时间,我们希望程序在等待时继续执行其他任务。
但是,我不确定在哪里进行等待调用。
调用低级数据库访问模块的高级模块应该使用await,还是应该使用低级模块?
我认为它应该是高级模块,因为它有更多的事情要做???
下面是一些示例代码,使用命令的正确或错误的地方?
高级控制器模块:
public async Task<IActionResult> Delete(int id, string email)
{
email = email.ToLower();
IUsers user = new Users();
// Async Await call here or in lower level module???
bool del = await Task.Run(() => user.DeleteUser(id, email));
if (del == true)
{
System.Diagnostics.Debug.WriteLine(String.Format("User Deleted"));
return Ok();
}
else
{
// If del is false or null
System.Diagnostics.Debug.WriteLine("Error. User ID: {0} Email: {1} didn't match, not deleted. ", id, email));
return BadRequest();
}
}
低级数据库访问模块:
// Connection String
IDbConnection dbConnection = new MySqlConnection(@"Server=127.0.0.1;blah;");
bool IUsers.DeleteUser(int id, string email)
{
using (dbConnection)
{
try
{
string cmd = @"DELETE from users WHERE ID=@Id AND EMAIL=@Email";
bool result = false;
// Should async await maybe be here???
var del = dbConnection.Execute(cmd, new { Id = id, Email = email });
//Change result to True if execute command went ahead
result = del > 0;
// Returns True or False
return result;
}
catch (Exception ex)
{
Console.WriteLine("Exception in Users.DeleteUser");
Console.WriteLine("Exception: {0}", ex.Message);
return false;
}
}
}
感谢您的反馈!
【问题讨论】:
-
一旦你开始使用 async/await,你应该从底部一直使用到顶部。所以你应该让
DeleteUser返回Task<bool>并等待,而不是Task.Run。你应该await一个ExcuteAsync方法或等效方法。 -
我推荐阅读this question。毫无疑问,其他人可以给出比我更连贯的答案,但简而言之:对 IO 使用异步方法(例如
ExecuteAsync),因为这允许在 IO 发生时暂停任务执行(释放资源以处理其他请求)。以您的方式使用Task.Run只是在等待 100% 同步 DB 代码执行时锁定任务使用的线程池中的线程,这意味着您总体上使事情变得更糟而不是更好。 -
异步自上而下/自下而上就是这样。
-
看看这个:Should I expose asynchronous wrappers for synchronous methods? 答案是否定的。这意味着如果你真的必须使用
Task.Run,你应该在最后一刻使用它。
标签: c# async-await