连接未关闭,连接当前处于打开状态。

11

我正在编写一款ASP.NET应用程序。在我的数据层中,使用SQL连接在查询之前和之后打开和关闭连接。SqlConnection被保存为单个类的私有字段。该类中的每个数据库调用都使用相同的结构:

        conn.Open();

        try
        {
            // database querying here
        }
        finally
        {
            conn.Close();
        }

然而,极少数情况下我会遇到异常信息“连接未关闭,连接当前状态为打开”。由于此问题很少从代码的不同部分发生,因此无法重现。我的应用程序涉及一些线程,但新线程也会创建新的数据层类和连接对象。

我不明白如何使用上述代码可能存在未关闭的连接。连接在打开后应该始终关闭,这样上述异常就不可能发生,对吗?


1
重要的是在哪里实例化你的conn对象? - Cyril Gandon
1
另外,使用 "using" 的问题在哪里? - Mitch Wheat
1
只需使用using语句?这将确保连接被关闭和处理。 - Philip Gullick
1
如果可能的话,尝试将你的连接包装在 using(SQLConnection conn = new SQLConnection(xxx)) { ... } 语句中,看看是否仍然能够重现错误。这样,在代码退出时,SQL连接会被GC清除。 - Marco
如果您使用了 DataReader,那么一定要关闭该对象。因为该对象是连接架构。 - Ramesh Rajendran
显示剩余3条评论
3个回答

15
很可能在try代码块中抛出了未处理的异常。请参见MSDN上有关try-finally的此说明:try-finally
在已处理的异常中,相关的finally块将被保证运行。但是,如果异常未得到处理,则finally块的执行取决于如何触发异常解除操作。
我建议无论如何都将连接包装在using块中:
using (SqlConnection connection = new SqlConnection(connectionString))
{
     //etc...
}

或者,将一个捕获块添加到 try-finally 中:

    conn.Open();

    try
    {

    }
    catch
    {

    }
    finally
    {
        conn.Close();
    }

谢谢,这解释了为什么conn.Close()有时不会运行。我曾经错误地认为finally {}无论如何都会运行。 - user2830395
没问题。如果这回答了你的问题,你应该考虑将其标记为答案,以帮助其他遇到类似问题的用户。 - DGibbs
1
@user2830395 你是正确的,finally 块无论如何都会执行,即使出现异常。如果这个答案中的代码解决了问题,那是因为另一个因素。 - Doug

4

在操作完成后,您应当尽快关闭连接。尽量缩短连接的开放时间。 不过,最好使用using语句,即使出现异常也会调用Dispose方法。

using (SqlConnection conn= new SqlConnection(conStr))
{
     //etc...
}

或者

1) 打开连接

2) 访问数据库

3) 关闭连接

 //conn.Open();

        try
        {
          conn.Open();
          //Your Code

        }
        finally
        {
           conn.Close();   
           conn.Dispose();//Do not call this if you want to reuse the connection
        }

1
如果try块内部出现问题,那么它不会关闭连接...关闭应该在finally中进行,这意味着conn需要在try之外声明。 - D3vy

-1
using (SqlConnection conn= new SqlConnection(conStr))
{

 // ETC

}

这是最好的解决方案,因为您可能希望再次重用连接。仅使用& dispose 不会对您有所帮助,因此在打开之前进行检查更好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接