1

質問:

次のコードが接続をリークしているのはなぜですか?

    public System.Data.DataTable GetDataTable()
    {
        System.Data.DataTable dt = new System.Data.DataTable();
        string strConnectionString = "Data Source=localhost;Initial Catalog=MyDb;User Id=SomeOne;Password=TopSecret;Persist Security Info=False;MultipleActiveResultSets=False;Packet Size=4096;";
        System.Data.SqlClient.SqlConnectionStringBuilder csb = new System.Data.SqlClient.SqlConnectionStringBuilder(strConnectionString);
        csb.IntegratedSecurity = true;


        string strSQL = "SELECT * FROM T_Benutzergruppen";

        using (System.Data.SqlClient.SqlConnection sqlcon = new System.Data.SqlClient.SqlConnection(csb.ConnectionString))
        {
            using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(strSQL, sqlcon))
            {
                if (sqlcon.State != System.Data.ConnectionState.Open)
                {
                    sqlcon.Open();
                }

                // First attempt
                //System.Data.SqlClient.SqlDataAdapter sqlda = new System.Data.SqlClient.SqlDataAdapter("SELECT * FROM T_Benutzer", sqlcon);
                //sqlda.Fill(dt);

                cmd.ExecuteNonQuery();
            }

            if(sqlcon.State != System.Data.ConnectionState.Closed)
                sqlcon.Close();
        }
        //sqlcon.ConnectionString = csb.ConnectionString;

        // Second attempt
        //System.Data.SqlClient.SqlDataAdapter sqlda = new System.Data.SqlClient.SqlDataAdapter("SELECT * FROM T_Benutzer", csb.ConnectionString);
        //sqlda.Fill(dt);


        return dt;
    }

SQL-Server アクティビティ モニターにアクセスすると、セッション 68 が表示されます

SELECT * FROM T_Benutzergruppen

追加の質問:

質問の場合:

ConnectionStringBuilder 以外のすべてをコメントアウトし、この関数で以下のコードのみを実行すると、接続もリークするのはなぜですか?

// Second attempt
System.Data.SqlClient.SqlDataAdapter sqlda = new System.Data.SqlClient.SqlDataAdapter("SELECT * FROM T_Benutzer", csb.ConnectionString);
sqlda.Fill(dt);

注:
executenonquery は意味がありません。テスト目的のためだけに存在します。

デバッガーで実行すると、sqlcon.Close(); が表示されます。

get が実行されるので、問題は

if(sqlcon.State != System.Data.ConnectionState.Closed)
4

2 に答える 2

3

Connection Pooling. Don't worry about it.

This is normal behavior.

http://msdn.microsoft.com/en-us/library/8xx3tyca(v=vs.100).aspx

于 2012-08-08T09:02:41.180 に答える
2

ADO.Net は、接続の作成に比較的コストがかかるため、再利用できるように接続をプールします。

通常、データベース サーバーへの接続は、時間のかかるいくつかの手順で構成されます。ソケットや名前付きパイプなどの物理チャネルを確立する必要があります。サーバーとの最初のハンドシェイクが発生する必要があります。接続文字列情報を解析する必要があります。サーバーによって接続が認証される必要があります。現在のチャネルに参加するためのチェックを実行する必要があります。取引など。

実際には、ほとんどのアプリケーションは、接続に 1 つまたはいくつかの異なる構成のみを使用します。これは、アプリケーションの実行中に、多くの同一の接続が繰り返し開いたり閉じたりすることを意味します。接続を開くコストを最小限に抑えるために、ADO.NET は接続プーリングと呼ばれる最適化手法を使用します。

http://msdn.microsoft.com/en-us/library/8xx3tyca(v=vs.100).aspx

また、.Close() を明示的に呼び出す必要はありません。usingブロックはIDisposable.Dispose()呼び出し、接続を適切に閉じます。

于 2012-08-08T09:04:13.747 に答える