3

我知道这是一个老问题。谷歌上千条声明说Connection will be closed in 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 行关闭。对吗?但是,连接在sleep第 11 行之后。

好的,尝试在下一行手动处理。但是在第 12 行之后,连接仍然在sleep.

好的,下一行是自动处理。但在第 13 行之后,连接仍在sleep.

好吧,这可能与GC. 所以我明确地跑去GC.Collect()尝试收集conn对象。但是在第 14 行之后,连接仍然在sleep.

连接实际上在第 15 行之后关闭。这意味着程序的结束。

在上面的程序中,创建了一个临时表#mytable。但是,只有在关闭连接时才会删除临时表。我们面临的问题是too many temp tables are in the database。(是的,我知道使用后应该删除临时表。)

我也试过

  1. 用于{ }创建一个新范围来包装连接。结果是一样的。

  2. 创建一个新线程以连接到数据库服务器。结果也是一样的。

  3. while(true) { Thread.Sleep(1000); GC.Collect(); }在方法结束时使用Main。结果也是一样的。

上面没有一个可以关闭SqlConnection。如何关闭连接?

4

1 回答 1

9

ADO.NET 中的连接池默认启用。这意味着当您“处理”您的连接时,您只是将它返回到池中。当您退出程序时,您显然最终会从池中释放所有内容。如果您想避免这种情况,您必须选择退出连接池。

要禁用,请将Pooling=false参数添加到连接字符串:

var connection = new SqlConnection(
    @"Data Source=(local)\SQLEXPRESS;Initial Catalog=TEST;Integrated " +      
    "Security=SSPI;Pooling=false;");
于 2013-04-23T02:37:22.087 回答