为什么我的using语句没有关闭连接?

时间:2012-02-03 18:16:51

标签: sql-server c#-4.0 ado.net sql-server-2008-r2

  

可能重复:
  Entity framework 4 not closing connection in sql server 2005 profiler

好吧,很多关于stackoverflow的开发人员说我不应该担心关闭我的连接:我的using语句会关闭我的连接,herehere以及整个网站。不幸的是,我没有看到它发生。这是我的代码:

    [Test, Explicit]
    public void ReconnectTest()
    {
        const string connString = "Initial Catalog=MyDb;Data Source=MyServer;Integrated Security=SSPI;Application Name=ReconnectTest;";
        for (int i = 0; i < 2000; i++)
        {
            try
            {
                using (var conn = new SqlConnection(connString))
                {
                    conn.Open();
                    using (var command = conn.CreateCommand())
                    {
                        command.CommandText = "SELECT 1 as a";
                        command.CommandType = CommandType.Text;
                        command.ExecuteNonQuery();
                    }
                    //conn.Close();
// optional breakpoint 1 below
                    }
                }
                catch(SqlException e)
                {
// breakpoint 2 below
                    Console.WriteLine(e);
                }
// breakpoint 3 below
            }
        }

当我启用所有断点并开始测试时,第一次迭代成功,我点击断点3.此时,连接仍然打开:我在Profiler中看到它,sp_who2也输出它。

我们假设此时我正在外面吃午饭,而且我的连接闲置了。因此,我们的生产服务器将其杀死。为了模仿它,我正在杀死SSMS的连接。

所以,当我点击F5并运行第二次迭代时,我的连接被终止了。不幸的是,它不会自动重新打开,因此ExecuteNonQuery会抛出以下异常:“发生了传输级错误”。当我运行第三次迭代时,我的连接实际打开:我将其视为Profiler中的事件,sp_who2也将其输出。

即使我没有注释我的conn.Close()命令,连接仍然没有关闭,当我从SSMS中删除它时,下一次迭代仍然会爆炸。

我错过了什么?为什么不能使用语句关闭我的连接?为什么Open()不能在第一次实际打开它,但下次成功?

此问题源于my previous one

1 个答案:

答案 0 :(得分:1)

当您拨打由SqlConnection.Dispose()阻止而执行的using时,连接未按此关闭。它被释放回连接池。

为了避免不断构建/拆除连接,连接池将保持连接打开以供您的应用程序使用。因此,连接仍然显示为开放是完全合理的。

之后发生了什么,我不能随便解释 - 我知道保持随机连接打开会导致这种情况,因为你的应用程序当然可以创建多个并发连接。