首页 > 解决方案 > 在哪里使用 Async 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;
            }
        }
    }

感谢您的反馈!

标签: c#async-await

解决方案


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

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

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

然后编译器会给你一个错误,说你应该标记DeleteUserasync并将其返回类型更改为Task<bool>. 您还需要更改IUsers界面来执行此操作:

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

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

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

推荐阅读