web-dev-qa-db-ja.com

C#でMySQLConnectionを使用すると正しく閉じない

最終的解決:

接続が接続プールに追加されました。それで私はそれを閉じました、しかしそれはまだ物理的に開いたままでした。 ConnectionStringパラメーター "Pooling = false"または静的メソッドMySqlConnection.ClearPool(connection)およびMySqlConnection.ClearAllPoolsを使用すると、問題を回避できます。問題は、アプリケーションを閉じたときに接続がまだ生きていたことであることに注意してください。閉めたのに。したがって、接続プールをまったく使用しないか、接続を閉じる前に特定のプールをクリアして問題を解決します。私の場合、最善の解決策を見つけるために時間をかけます。

答えてくれたすべての人に感謝します!これは、C#の概念をよりよく理解するのに役立ち、有用な入力から多くのことを学びました。 :)

===

元の問題:

しばらく検索しましたが、問題の解決策が見つかりませんでした。C#を初めて使用し、MySql接続を簡単にするクラスを作成しようとしています。私の問題は、接続を開いて閉じた後です。それはまだデータベースで開いていて、中止されます。

もちろん、「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()メソッドが呼び出されて正しく実行されました。何が足りないのですか?私が間違ったことや誤解したことはありますか?

どんな助けでも大歓迎です!

ご挨拶、サイモン

追伸:念のため、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;
                }
            }
        }
    }

データを取得できるように機能しますが、それでも同じ問題があります。接続が適切に閉じられていません。 :(

17
Skalli

Mysqlconnectionについてはよくわかりませんが、SQLサーバーのカウンターパートは接続プールを使用し、closeを呼び出しても閉じず、代わりに接続プールに入れます。

編集:Reader、Command、およびConnectionオブジェクトを必ず破棄してください。

編集:ConnectionStringパラメーター "Pooling = false"または静的メソッドMySqlConnection.ClearPool(connection)およびMySqlConnection.ClearAllPools()で解決

19
Peter

CommandとDataReaderもusingステートメントでラップする必要があります。

5
SLaks

Mysqlのドキュメントによると、MySQLConnectionはスコープ外になっても閉じられません。したがって、using内で使用しないでください。

引用...「MySqlConnectionがスコープ外になった場合、それは閉じられません。したがって、MySqlConnection.CloseまたはMySqlConnection.Disposeを呼び出して、接続を明示的に閉じる必要があります。」

2
flobadob