Использование MySQLConnection в С# не закрывается должным образом

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

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

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

===

Исходная проблема:

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

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

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

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() вызывается и выполняется правильно. Что мне не хватает? Что-то я сделал неправильно или неправильно понял?

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

Привет, Саймон

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;
                }
            }
        }
    }

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

Ответы

Ответ 1

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

Изменить: убедитесь, что вы выбрали объект Reader, Command и Connection!

Изменить: Решено с параметром ConnectionString "Пул = ложь" или статические методы MySqlConnection.ClearPool(соединение) и MySqlConnection.ClearAllPools()

Ответ 2

Вам нужно также обернуть команду и DataReader в операторы using.

Ответ 3

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

Цитата... "Если MySqlConnection выходит из сферы действия, он не закрыт, поэтому вы должны явно закрыть соединение, вызвав MySqlConnection.Close или MySqlConnection.Dispose."

Ответ 4

Посмотрите на использование чего-то вроде этого:

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;
        }
    }
}