[英]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 database
有too many temp tables are in the database
。 (Yes, I know temp tables should be dropped after use.) (是的,我知道临时表应该在使用后丢弃。)
I also tried to 我也试过
use { }
to create a new scope to wrap the connection. 使用
{ }
创建一个新的范围来包装连接。 The result is the same. 结果是一样的。
create a new thread to connect to the DB server. 创建一个新线程以连接到数据库服务器。 The result is also the same.
结果也是一样的。
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.