【问题标题】:.NET Core wont close my MySqlConnection.NET Core 不会关闭我的 MySqlConnection
【发布时间】:2017-06-20 14:33:06
【问题描述】:

我有一个使用 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

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

【问题讨论】:

    标签: c# azure .net-core cleardb mysqlconnection


    【解决方案1】:

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

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

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

    【讨论】:

    • 我只是厌倦了禁用池,因为其他人在互联网上建议它。但是当程序运行 10 分钟左右时,我将关闭 ClearDB 中的连接。之后程序仍在运行时它不会连接。
    • @mmarkvoort 我不相信连接失败是连接池耗尽的结果。就像我说的,连接在实际数据库中持续存在是正常的。除非您抛出异常(在这种情况下,您的所有处置可能不会发生)我发现您显示的代码不太可能是问题。
    • 代码不是问题,我知道。我可能在 10 分钟后关闭连接后打开新连接时做错了。
    【解决方案2】:

    代码 sn -p 中的using 语句应该关闭您的连接。但是,我不确定它如何与async 交互,或者ClearDB 与普通MySql 有何不同。鉴于问题中的问题以及缺乏明确性,您可以试试这个,看看它是否有帮助:

    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() 调用的位置)。

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

    【讨论】:

    • 感谢您的快速回答,但您的解决方案不起作用。当我开始程序。它是第一次工作,但是当我强制退出 cleardb 网页中的连接并重试时。它不会再连接了。而且我没有禁用连接池,我只是尝试这样做会有所作为。我的方法不是静态的。
    • 忘记添加参数了。
    • "when I force quit the connection within cleardb webpage and try again. It wont connect anymore" 不要那样做!
    • 为什么不呢?相当于等了10分钟ClearDB会自动关闭吧?
    • 不,不是。打开新连接涉及(除其他外)网络延迟和复杂/昂贵的协商,包括验证或计算密码哈希或证书。连接池试图通过在后台保持多个连接打开以供重复使用而不是总是立即关闭它们来避免这种情况。您应该在 ClearDB 控制台中看到一些挥之不去的打开连接,当您强制关闭这些连接时,您正在破坏该机制。
    猜你喜欢
    • 2011-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-09
    • 2021-07-11
    • 1970-01-01
    • 2020-07-11
    • 1970-01-01
    相关资源
    最近更新 更多