简体   繁体   中英

Why is my code leaking connections?

Question:

Why is the following code leaking connections ?

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

If I go into SQL-Server activity monitor, I see Session 68

SELECT * FROM T_Benutzergruppen

Additional question:

If question:

If I comment out everything except the ConnectionStringBuilder, and only execute the below code in this function, why does it leak a connection, too ?

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

Note:
The executenonquery makes no sense, it's just there for testing purposes.

If I let it run in the debugger, I see that sqlcon.Close();

get's executed, so the problem is not the

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

Connection Pooling. Don't worry about it.

This is normal behavior.

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

ADO.Net pools connections so that they can be re-used because they are relatively expensive to create.

Connecting to a database server typically consists of several time-consuming steps. A physical channel such as a socket or a named pipe must be established, the initial handshake with the server must occur, the connection string information must be parsed, the connection must be authenticated by the server, checks must be run for enlisting in the current transaction, and so on.

In practice, most applications use only one or a few different configurations for connections. This means that during application execution, many identical connections will be repeatedly opened and closed. To minimize the cost of opening connections, ADO.NET uses an optimization technique called connection pooling.

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

Also, there is no need to explicitly call .Close(). Your using block will call IDisposable.Dispose() , which will close the connection properly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM