简体   繁体   中英

No Way to Close SqlConnection

I know this is an old question. Thousands of statements on Google say Connection will be closed in Dispose() . However, who did really verify that?

I found that a SqlConnection is no way to close . I have a simple program (with line number on left).

  class Program
  {
    static void Main(string[] args)
1   {
2        var connectionString = "Data Source=localhost;Initial Catalog=master;Integrated Security=SSPI;";
3        using (var conn = new SqlConnection(connectionString))
5        {
6            using (var cmd = new SqlCommand("create table #mytable(col1 int);", conn))
7            {
8                conn.Open();
9                cmd.ExecuteNonQuery();
10           }
11           conn.Close();
12           conn.Dispose();
13       }
14       GC.Collect();
15   }
  }

And I have a T-SQL statement for checking active connection

exec sp_who2

I stepped line by line with the Debugger, meanwhile, I checked the active connection with sp_who2 .

Everyone is expecting the connection should be closed on line 11. Right? However, the connection is in sleep after line 11.

Okay, try manually disposal on next line. But after line 12, the connection is still in sleep .

Okay, next line is the auto-disposal. But after line 13, the connection is still in sleep .

Okay, it may be related to the GC . So I explicitly ran GC.Collect() to try to collect the conn object. But after line 14, the connection is still in sleep .

The connection actually closed after line 15 . That means the end of program.

In the program above, a temp table #mytable is created. However, the temp table will only be dropped if the connection is closed. The problem we are facing is too many temp tables are in the database . (Yes, I know temp tables should be dropped after use.)

I also tried to

  1. use { } to create a new scope to wrap the connection. The result is the same.

  2. create a new thread to connect to the DB server. The result is also the same.

  3. use while(true) { Thread.Sleep(1000); GC.Collect(); } while(true) { Thread.Sleep(1000); GC.Collect(); } while(true) { Thread.Sleep(1000); GC.Collect(); } at the end of the Main method. The result is also the same.

None of them above can close the SqlConnection. How to close a connection?

Connection pooling in ADO.NET is enabled by default. This means that when you "dispose" your connection, you are merely returning it to the pool. When you exit the program, you are obviously finally releasing everything from the pool. If you want to avoid this, you have to opt-out of connection pooling.

To disable, add the Pooling=false argument to your connection string:

var connection = new SqlConnection(
    @"Data Source=(local)\SQLEXPRESS;Initial Catalog=TEST;Integrated " +      
    "Security=SSPI;Pooling=false;");

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