0

我有一个使用 MySqlConnection 类的 .NET Core 程序。我的数据库是存储在 Azure 中的 ClearDB 数据库。

当我启动该程序时,它会正常工作。但是当我等待 10 分钟什么都不做时,它不会再连接到数据库(超时?)。重新启动程序,它再次工作。

查看 ClearDB 网页上的连接时,当我在程序中关闭它时,它并没有关闭。正如我在 ClearDB 网页中看到的那样,大约 10 分钟后它会自动关闭。但是随着程序仍在运行,它将不再连接到数据库。重启程序是唯一的解决方案。

现在的代码看起来像这样:

private static async Task<uint> getDeviceId(string macAddress)
{
    using (var connection = new MySqlConnection(ConnectionString))
    {
        uint returnvalue = 0;
        var cmd = connection.CreateCommand() as MySqlCommand;
        cmd.CommandText = @"SELECT id FROM devices WHERE mac = '" + macAddress + "'";
        connection.Open();
        Console.WriteLine(connection.State);

        DbDataReader reader = await cmd.ExecuteReaderAsync();
        using (reader)
        {
            while (await reader.ReadAsync())
            {
                returnvalue = await reader.GetFieldValueAsync<uint>(0);
            }
        }
        reader.Dispose();
        cmd.Dispose();
        return returnvalue;
    }
}

我尝试了以下方法:

  • 使用语句
  • 关闭/处理连接、阅读器和命令
  • 连接字符串中的 Pooling=false

但它们都不起作用。有人有想法吗?

4

2 回答 2

0

using代码片段中的语句应该关闭您的连接。但是,我不确定它是如何与正常交互的async,或者与正常的有什么不同。鉴于问题中的问题以及缺乏明确性,您可以试试这个,看看它是否有帮助:ClearDBMySql

private static async Task<uint> getDeviceId(string macAddress)
{
    uint returnvalue = 0;
    MySqlConnection connection;
    try
    {
        connection = new MySqlConnection(ConnectionString);

        var cmd = connection.CreateCommand() as MySqlCommand;
        //Don't EVER(!) use string concatenation like that in a query!
        cmd.CommandText = @"SELECT id FROM devices WHERE mac = @macAddress";
        cmd.Parameters.Add("@macAddress", MySqlDbType.VarChar, 18).Value = macAddress;
        connection.Open();
        Console.WriteLine(connection.State);

        DbDataReader reader = await cmd.ExecuteReaderAsync();
        using (reader)
        {
            while (await reader.ReadAsync())
            {
                returnvalue = await reader.GetFieldValueAsync<uint>(0);
            }
        }
        reader.Dispose();
        cmd.Dispose();

    }
    finally
    {
        connection.Close();
        connection.Dispose();
    }
    return returnvalue;
}

一个using块基本上只是重新编写您的代码try/finally,因此手动执行此步骤有时可以使调试更容易(您可以记录它在哪里.Close()调用)。

如果这确实解决了问题,我不会止步于此,而是从那里开始,看看你能得到多接近“正常”代码。我在这里还担心您禁用了连接池,并且此方法是静态的。

于 2017-06-20T15:03:40.477 回答
0

假设 MySql 提供程序类似于 MSSQL 提供程序,它实际上并没有关闭数据库中的连接,它只是将其释放回池中。

你不想禁用池化,你会扼杀效率。

这是设计使然,也是您想要的。

于 2017-06-20T15:02:17.333 回答