C#MySql函数(输入命令字符串,返回读取器)

C#MySql函数(输入命令字符串,返回读取器),c#,mysql,C#,Mysql,我已经编写了一个函数来执行MySQL语句。在这个函数中,我在一条语句中给出并返回MySqlDataReader,但问题是我的函数没有关闭连接。使用该程序一段时间后,由于无法打开新连接,程序崩溃。这是我在尝试打开新连接时遇到的错误: 连接错误:超时已过期。之前的超时时间已过 从池中获取连接。这可能已经发生了 因为所有池连接都在使用中,并且最大池大小为 达到 我的代码如下所示: MySQL类: class mySql { string cs = "server=123.123.123.12

我已经编写了一个函数来执行MySQL语句。在这个函数中,我在一条语句中给出并返回MySqlDataReader,但问题是我的函数没有关闭连接。使用该程序一段时间后,由于无法打开新连接,程序崩溃。这是我在尝试打开新连接时遇到的错误:

连接错误:超时已过期。之前的超时时间已过 从池中获取连接。这可能已经发生了 因为所有池连接都在使用中,并且最大池大小为 达到

我的代码如下所示: MySQL类:

class mySql
{

    string cs = "server=123.123.123.123;" +
                "uid=abcabc;" +
                "pwd=123456;" +
                "database=overflow_test;";

    private MySqlConnection conn_f()     // create a Connection
    {
        MySql.Data.MySqlClient.MySqlConnection conn;

        conn = new MySql.Data.MySqlClient.MySqlConnection();

        conn.ConnectionString = cs;

        try
        {
            conn.Open();
            return conn;
        }
        catch
        {
            return null;
        }
    }
    public MySqlDataReader CMD_f(string comand) //execute SQL Command
    {
        MySql.Data.MySqlClient.MySqlCommand cmd;
        cmd = new MySql.Data.MySqlClient.MySqlCommand();
        MySqlConnection conn = conn_f();
        cmd.Connection = conn;

        cmd.CommandText = comand;
        cmd.Prepare();
        rdr = cmd.ExecuteReader();
        return rdr;
    }
}
还有一个我如何在Main类中使用它的示例

class main{
mySql DB = new mySql();
public void main(){
MySqlDataReader rdr = DB.CMD_f("SELECT * FROM tbl_kategorie");
        int i = 0;
        while (rdr.Read())
        {
            string str = rdr.GetString(1);
            Console.WriteLine(str);
        }
}
有人有办法解决这个问题。
诚挚问候LFS96(费边·哈姆森)

主要问题是代码中的不平衡。
CMD\u f
方法创建一个连接,但不承担任何责任。您应该将创建连接的方法公开,以便您可以在关闭连接的代码中对此负责

这是一个更大的更改,所以首先让我们看一个较小的更改来修复代码

数据读取器应将数据连接公开为
连接
属性。我在文档中没有看到这一点,所以它可能没有,但是.NET framework中的数据读取器有

如果属性已公开,则可以进行快速修复,以使代码在进行最小更改的情况下工作:

MySqlDataReader rdr = DB.CMD_f("SELECT * FROM tbl_kategorie");
int i = 0;
while (rdr.Read())
{
    string str = rdr.GetString(1);
    Console.WriteLine(str);
}
rdr.Close();
rdr.Connection.Close();

如果将
conn\u f
方法公开,而不在
CMD\u f
方法中调用它,则可以编写更健壮的代码,即使出现错误,也不会使连接或数据读取器挂起。这是代码中一个更大的变化,但当您有时间实现和测试它时,这绝对值得付出努力。使用
使用
块以确保始终正确放置对象,可使代码更具弹性:

using (MySqlConnection conn = DB.conn_f()) {
  using (MySqlDataReader rdr = DB.CMD_f(conn, "SELECT * FROM tbl_kategorie")) {
    int i = 0;
    while (rdr.Read()) {
      string str = rdr.GetString(1);
      Console.WriteLine(str);
    }
  }
}
旁注:C#中的标识符往往是描述性的。我建议使用
DB.CreateConnection
DB.ExecuteReader
等名称,而不是
DB.conn\u f
DB.CMD\u f