C # MySqlConnection не закрывается - PullRequest
2 голосов
/ 04 января 2011

У меня есть приложение, которое запускает команду (запрос) 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;
    }

PS «Новая база данных MySQL. (DbName, this));»это мой сделанный класс, который хранит только структуру БД, может считаться неуместным.

Точная ошибка, которую я получаю, это 'max_user_connections'.в строке connection.open следующего раза, когда запрос должен быть запущен.

Ответы [ 6 ]

7 голосов
/ 04 января 2011

Вместо того, чтобы отслеживать все вызовы Open / Close / Dispose повсюду, я бы рекомендовал просто заменить все из них на using операторов .Это обеспечит ясность ожидаемой области действия каждого объекта и его уничтожение / удаление после выхода из этой области.

2 голосов
/ 23 апреля 2014

Close() и using помогут в одиночку решить вашу проблему, поскольку ADO.NET использует собственный пул соединений, и по умолчанию соединения не закрываются до тех пор, пока программа не закроется. Существует несколько вариантов решения этой проблемы, но следует учитывать влияние на производительность и действительно ли это желаемое поведение для вашего приложения.

Для получения дополнительной информации читайте: Пул соединений с сервером SQL (ADO.NET)

1 голос
/ 04 января 2011

Наряду с приведенными выше советами using при создании переменной sqlDR следует использовать поведение команды CloseConnection, чтобы закрыть фактическое соединение, если это ваше намеченное действие.Как отмечено в документации здесь .

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();

0 голосов
/ 04 января 2011

Я изменил свой код, чтобы использовать 1 соединение и оставил его открытым, и при тестировании я обнаружил ошибку, что устройство чтения данных должно быть закрыто.Теперь, так как все мои запросы не закрывали объект dataReader (я использовал dataTable.Load (cmd.ExecuteReader ()).) Я думаю, что проблема может быть там.

Сохранение 1 открытого соединения работало отлично, поэтому я нене знаю, что вызвало не закрытие проблемы.Я догадываюсь, что это был DataReader, не закрывающийся сам по себе.

0 голосов
/ 04 января 2011

Я рекомендую использовать пул соединений в сочетании с классом MySqlHelper, передавая строку соединения в качестве первого аргумента. Это позволяет MySQL при необходимости открывать соединение или сохранять его открытым в соответствии с пулом cfg без необходимости знать об этом.

0 голосов
/ 04 января 2011

когда используется ключевое слово «using», что происходит. Когда сборщик мусора активирует, он сначала удаляет объекты, которые были объявлены в операторе using.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...