C#MySqlConnection不会关闭

时间:2011-01-03 23:24:03

标签: c# mysql connection

我有一个应用程序触发mysql命令(查询)“显示数据库”,查询工作并正确返回但我无法关闭我的连接。我使用的用户同时允许24个连接,所以问题突然出现在我的程序中,但是将允许的连接减少到2表明我甚至无法关闭第一个查询(不在循环中)。代码如下:

    protected override Dictionary<string, Jerow_class_generator.Database> loadDatabases()
    {
        MySqlConnection sqlCon = new MySqlConnection(this.ConnectionString);
        sqlCon.Open();

        MySqlCommand sqlCom = new MySqlCommand();
        sqlCom.Connection = sqlCon;
        sqlCom.CommandType = CommandType.Text;
        sqlCom.CommandText = "show databases;";

        MySqlDataReader sqlDR;
        sqlDR = sqlCom.ExecuteReader();

        Dictionary<string, Jerow_class_generator.Database> databases = new Dictionary<string, Jerow_class_generator.Database>();
        string[] systemDatabases = new string[] { "information_schema", "mysql" };

        while (sqlDR.Read())
        {
            string dbName = sqlDR.GetString(0);
            if (!systemDatabases.Contains(dbName))
            {
                databases.Add(sqlDR.GetString(0), new MySQL.Database(dbName, this));
            }
        }

        sqlCom.Dispose();
        sqlDR.Close();

        sqlCon.Close();
        sqlCon.Dispose();
        return databases;
    }

P.S。 'New MySQL.Database(dbName,this));'是我自己制作的只存储数据库结构的类,可以认为是不相关的。

我得到的确切错误是'max_user_connections'。在下次需要触发查询时的connection.open行上。

6 个答案:

答案 0 :(得分:7)

我建议您只使用using statements替换所有内容,而不是跟踪所有Open / Close / Dispose来电。这将确保每个对象的预期范围是明确的,并且在退出该范围时将被销毁/处置。

答案 1 :(得分:2)

Close()using将单独解决您的问题,因为ADO.NET正在使用自己的连接池,默认情况下连接在程序关闭之前不会关闭。解决这个问题的方法很少,但考虑到性能影响,这是您的应用程序真正需要的行为。

有关详细信息,请参阅:SQL Server Connection Pooling (ADO.NET)

答案 2 :(得分:1)

除了上面的using建议,在创建sqlDR变量时,如果这是您的预期操作,则应使用CloseConnection命令行为关闭实际连接。如文档here中所述。

When the command is executed, the associated Connection object is closed when the associated DataReader object is closed.

因此,实例化读者的代码如下所示:

    //to instantiate your variable
    MySqlDataReader sqlDR;
    sqlDR = sqlCom.ExecuteReader(CommandBehavior.CloseConnection);

   //closing your datareader reference here will close the connection as well
   sqlDR.Close();

如果您使用上述方法将所有代码包装在using块中,则除了Close()之外,您不需要任何Dispose()sqlDR.Close();方法

答案 3 :(得分:0)

当使用“使用”关键词时会发生什么事情。当垃圾收集器激活它时,首先处理使用语句删除的对象。

答案 4 :(得分:0)

我建议将连接池与MySqlHelper类结合使用,将连接字符串作为第一个参数传递。这允许MySQL在必要时打开连接,或者根据池化cfg保持打开状态,而不必了解它。

答案 5 :(得分:0)

我将我的代码更改为使用1个连接并保持打开状态,并且在测试时遇到了一个错误,即应关闭datareader。现在因为我的所有查询都没有关闭dataReader对象(我使用了dataTable.Load(cmd.ExecuteReader())。)我认为问题可能就在那里。

保持1个开放式连接工作正常,所以我不知道是什么原因导致了未关闭的问题。我猜这是dataReader本身没有关闭。