C# DB异步调用的性能

C# DB异步调用的性能,c#,async-await,C#,Async Await,我有以下代码: public static async Task<uint?> GetJobAsync(string name) { return await Program.Database.PerformQueryAsync<uint?>(async (command) => { command.CommandText = "SELECT `job` FROM `people` WHERE `name`=@name;";

我有以下代码:

public static async Task<uint?> GetJobAsync(string name)
{
    return await Program.Database.PerformQueryAsync<uint?>(async (command) =>
    {
        command.CommandText = "SELECT `job` FROM `people` WHERE `name`=@name;";
        command.Parameters.Add(new MySqlParameter("name", name));
        MySqlDataReader reader = await command.ExecuteReaderAsync() as MySqlDataReader;
        if (!reader.HasRows)
            return null;
        reader.Read();

        return reader.GetUInt32(0);
    });
}

public async Task<T> PerformQueryAsync<T>(Func<MySqlCommand, Task<T>> operationAsync)
{
    try
    {
        using (MySqlCommand command = CreateCommand())
            return await operationAsync(command);
    }
    catch (MySqlException ex)
    {
        if (ex.GetBaseException() is SocketException)
        {
            Console.WriteLine("MySQL connection was broken. Reconnecting...");

            if (!IsConnected())
                Connect();

            using (MySqlCommand command = CreateCommand())
                return await operationAsync(command);
        }

        throw;
    }
}
公共静态异步任务GetJobAsync(字符串名称)
{
返回wait Program.Database.PerformQueryAsync(异步(命令)=>
{
command.CommandText=“从`people`中选择`job`,其中`name`=@name;”;
Add(新的MySqlParameter(“name”,name));
MySqlDataReader=wait命令。ExecuteReaderAsync()作为MySqlDataReader;
如果(!reader.HasRows)
返回null;
reader.Read();
返回读取器GetUInt32(0);
});
}
公共异步任务PerformQueryAsync(Func operationAsync)
{
尝试
{
使用(MySqlCommand=CreateCommand())
返回等待操作同步(命令);
}
捕获(MySqlException-ex)
{
如果(例如GetBaseException()是SocketException)
{
WriteLine(“MySQL连接已断开。正在重新连接…”);
如果(!IsConnected())
Connect();
使用(MySqlCommand=CreateCommand())
返回等待操作同步(命令);
}
投掷;
}
}
第二个函数作为底层MySQL连接存在,通常
wait\u timeout
s。我的SQL查询很短,花费的时间更少。但是,调用了3个异步方法来获取此信息。这是一个很好的异步用例吗?我应该转换为同步代码吗


我的担忧源于Microsoft杂志文章中的建议,该文章显示了为简单异步调用生成的Il代码。

我认为您不应该转换为同步代码,因为异步可以提供更好的性能。在这种情况下,您的代码不会被阻塞-因此系统将使用更少的线程…

答案是这取决于您的上下文。如果这些方法是在具有活动的同步上下文的上下文中运行的SynchronizationContext;e、 WinForms、ASP.NET、WPF,那么您几乎可以肯定地更喜欢异步,这样就不会阻塞主线程。这在您的情况下尤其重要,因为您暗示您的数据库操作经常超时,在此期间主线程将一直被阻塞


Stephen Toub您链接到的文章一如既往地优秀,但正如他所说的,特别是在他的其他文章中,与大多数I/O操作的成本相比,异步开销是完全微不足道的,尤其是对数据库的网络调用。

首先,在处理catch块并重试查询后,不要在该块上重新显示异常。然后该函数需要返回其他内容;我想让它不被处理,这样它就有可能被进一步捕获(除非有更好的方法,我找不到)。如果网络调用是通过本地主机进行的,这仍然适用吗?@Hele:是-数据库(可能)的磁盘I/O和所需的进程间通信仍将远远超过任何异步开销。