我知道这是一个老问题。谷歌上成千上万的语句都说连接会在Dispose()中关闭
。然而,谁真正核实了呢?
我发现一个SqlConnection
没有任何关闭的方法。我有一个简单的程序(带左侧行号)。
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 }
}
我有一个T-SQL语句用于检查活动连接。
exec sp_who2
我使用调试器逐行检查程序,同时使用
sp_who2
检查活动连接。在第11行之后,每个人都期望连接应该被关闭。不是吗?然而,在第11行之后,连接处于
sleep
状态。好的,尝试在下一行手动处理。但是在第12行之后,连接仍处于
sleep
状态。好的,下一行是自动处理。但是在第13行之后,连接仍处于
sleep
状态。好的,这可能与
GC
有关。因此,我明确运行了 GC.Collect()
来尝试收集 conn
对象。但是在第14行之后,连接仍处于 sleep
状态。
实际上,在第15行之后连接已经关闭。这意味着程序结束了。在上面的程序中,创建了一个临时表
#mytable
。但是,只有在连接关闭时才会删除临时表。我们面临的问题是 数据库中存在太多的临时表
。(是的,我知道应该在使用后删除临时表。)我还尝试过:
使用
{ }
创建新范围以包装连接。结果相同。创建一个新线程连接到数据库服务器。结果也相同。
在
Main
方法的结尾使用while(true) { Thread.Sleep(1000); GC.Collect(); }
。结果也相同。