简体   繁体   English

无法关闭SqlConnection

[英]No Way to Close SqlConnection

I know this is an old question. 我知道这是一个老问题。 Thousands of statements on Google say Connection will be closed in Dispose() . Google上的数千条声明称Connection will be closed in Dispose() However, who did really verify that? 但是,谁真的验证了?

I found that a SqlConnection is no way to close . 我发现SqlConnection 无法关闭 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 我有一个用于检查活动连接的T-SQL语句

exec sp_who2

I stepped line by line with the Debugger, meanwhile, I checked the active connection with sp_who2 . 一步一步地跟调试器一起走了,同时,我用sp_who2检查了活动连接。

Everyone is expecting the connection should be closed on line 11. Right? 每个人都期望连接应该在第11行关闭。对吗? However, the connection is in sleep after line 11. 但是,连线在第11行之后处于sleep

Okay, try manually disposal on next line. 好的,尝试下一行手动处理。 But after line 12, the connection is still in sleep . 但在第12行之后,连接仍然处于sleep

Okay, next line is the auto-disposal. 好的,下一行是自动处理。 But after line 13, the connection is still in sleep . 但在第13行之后,连接仍处于sleep

Okay, it may be related to the GC . 好的,它可能与GC So I explicitly ran GC.Collect() to try to collect the conn object. 所以我明确地运行GC.Collect()来尝试收集conn对象。 But after line 14, the connection is still in sleep . 但是在第14行之后,连接仍处于sleep

The connection actually closed after line 15 . 连接实际上在第15行之后关闭 That means the end of program. 这意味着计划的结束。

In the program above, a temp table #mytable is created. 在上面的程序中,创建了临时表#mytable 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 . 我们面临的问题是too many temp tables are in the databasetoo 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(); } 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. while(true) { Thread.Sleep(1000); GC.Collect(); }在的末端Main方法。 The result is also the same. 结果也是一样的。

None of them above can close the SqlConnection. 上面没有一个可以关闭SqlConnection。 How to close a connection? 如何关闭连接?

Connection pooling in ADO.NET is enabled by default. 默认情况下启用ADO.NET中的连接池。 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: 要禁用,请将Pooling=false参数添加到连接字符串:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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