在哪里使用 Async Await 与数据库?在高级模块还是低级模块中?

时间:2021-04-05 02:27:03

标签: c# async-await

我知道我们应该在访问数据库时使用 async 和 await,因为处理这个请求需要时间,我们希望程序在等待时继续执行其他任务。

但是,我不确定在哪里进行此等待调用。

调用低级数据库访问模块的高级模块应该使用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;
            }
        }
    }

感谢您的反馈!

1 个答案:

答案 0 :(得分:2)

在大多数情况下,您根本不应该在 ASP.NET 上使用 Task.Run 。特别是在这种情况下,您绝对不应该使用 Task.Run,因为它只是在后台线程上运行同步代码 - 我称之为“假异步”。

我建议开始在最低级别使用异步,然后从那里逐步提高。在这种情况下:

var del = await dbConnection.ExecuteAsync(cmd, new { Id = id, Email = email });

然后编译器会提示您将DeleteUser 标记为async 并将其返回类型更改为Task<bool> 的错误。您还需要更改 IUsers 界面才能执行此操作:

async Task<bool> IUsers.DeleteUserAsync(int id, string email)

并更新所有调用它的东西,让你的控制器方法看起来像:

bool del = await user.DeleteUserAsync(id, email);