Использование MySQLConnection в C # не закрывается должным образом - PullRequest
15 голосов
/ 06 апреля 2011

Окончательное решение:

Соединение было добавлено в пул соединений. Я закрыл его, но он все еще оставался физически открытым. С помощью параметра ConnectionString «Pooling = false» или статических методов MySqlConnection.ClearPool (connection) и MySqlConnection.ClearAllPools можно избежать этой проблемы. Обратите внимание, что проблема заключалась в том, что соединение было еще живым, когда я закрывал приложение. Хотя я закрыл это. Поэтому я либо вообще не использую пул соединений, либо очищаю определенный пул перед закрытием соединения, и проблема решена. Я найду время, чтобы выяснить, какое решение лучше в моем случае.

Спасибо всем, кто ответил! Это помогло мне лучше понять концепции C #, и я многому научился из полезного. :)

===

Оригинальная проблема:

Я уже некоторое время искал и не нашел решения для моей проблемы: Я новичок в C # и пытаюсь написать класс, чтобы сделать MySql Connections проще. Моя проблема, после того, как я открываю соединение и закрываю его. Он все еще открыт в базе данных и прерывается.

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

Вот как выглядит мой код:

using (DatabaseManager db = new DatabaseManager())
{
using (MySqlDataReader result = db.DataReader("SELECT * FROM module WHERE Active=1 ORDER BY Sequence ASC"))
{
    foreach (MySqlDataReader result in db.DataReader("SELECT * FROM module WHERE Active=1 ORDER BY Sequence ASC"))
    {
        //Do stuff here
    }
}
}

Менеджер баз данных класса открывает соединение и закрывает его при удалении:

public DatabaseManager()
{
    this.connectionString = new MySqlConnectionStringBuilder("Server=localhost;Database=businessplan;Uid=root;");
    connect();
}
private bool connect()
{
    bool returnValue = true;
    connection = new MySqlConnection(connectionString.GetConnectionString(false));
    connection.Open();
}

public void Dispose()
{
    Dispose(true);
}

public void Dispose(bool disposing)
{
    if (disposing)
    {
        if (connection.State == System.Data.ConnectionState.Open)
        {
            connection.Close();
            connection.Dispose();
        }
    }
    //GC.SuppressFinalize(this);//Updated
}
//Updated
//~DatabaseManager()
//{
//  Dispose(false);
//}

Итак, я проверил это в отладчике и метод Dispose () - вызывается и выполняется правильно. Что мне не хватает? Что-то я не так сделал или неправильно понял?

Любая помощь приветствуется!

Привет, Simon

P.S .: На всякий случай, DataReader () - метод (обновленная версия):

public IEnumerable<IDataReader> DataReader(String query)
    {
        using (MySqlCommand com = new MySqlCommand())
        {
            com.Connection = connection;
            com.CommandText = query;
            using (MySqlDataReader result = com.ExecuteReader(System.Data.CommandBehavior.CloseConnection))
            {
                while (result.Read())
                {
                    yield return (IDataReader)result;
                }
            }
        }
    }

Хорошо, я пытался использовать доходность:

foreach (MySqlDataReader result in db.DataReader("SELECT * FROM module WHERE Active=1 ORDER BY Sequence ASC"))
{
    //...
}

И я изменил DataReader-метод:

public IEnumerable<IDataReader> DataReader(String query)
    {
        using (MySqlCommand com = new MySqlCommand())
        {
            com.Connection = connection;
            com.CommandText = query;
            using (MySqlDataReader result = com.ExecuteReader())
            {
                while (result.Read())
                {
                    yield return (IDataReader)result;
                }
            }
        }
    }

Это работает так, что я могу получить данные, но у меня все еще остается та же проблема: соединение не закрыто должным образом. (

Ответы [ 4 ]

16 голосов
/ 06 апреля 2011

Я не уверен насчет mysqlconnection, но счетчик сервера sql использует пул соединений и не закрывается при вызове close, вместо этого он помещает его в пул соединений!

Edit: убедитесь, что вы используете Reader, Command,и объект подключения!

Редактирование: решается с помощью параметра ConnectionString «Pooling = false» или статических методов MySqlConnection.ClearPool (connection) и MySqlConnection.ClearAllPools ()

5 голосов
/ 06 апреля 2011

Вам нужно также обернуть Команду и Читатель Данных в операторы using.

2 голосов
/ 05 сентября 2014

Согласно документам mysql, MySQLConnection не закрывается, когда выходит из области видимости. Поэтому вы не должны использовать его внутри.

Цитата ... «Если MySqlConnection выходит из области видимости, он не закрывается. Поэтому необходимо явно закрыть соединение, вызвав MySqlConnection.Close или MySqlConnection.Dispose.»

0 голосов
/ 06 апреля 2011

Взгляните на что-то вроде этого:

private static IEnumerable<IDataRecord> SqlRetrieve(
    string ConnectionString, 
    string StoredProcName,
    Action<SqlCommand> AddParameters)
{
    using (var cn = new SqlConnection(ConnectionString))
    using (var cmd = new SqlCommand(StoredProcName, cn))
    {
        cn.Open();
        cmd.CommandType = CommandType.StoredProcedure;

        if (AddParameters != null)
        {
            AddParameters(cmd);
        }

        using (var rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
        {
            while (rdr.Read())
                yield return rdr;
        }
    }
}
...