在Dispose方法中关闭数据库连接是正确的吗?

5
我怀疑我们某个应用程序中使用的数据库连接并不总是关闭。我去查看了代码,发现了一个名为 DataProvider 的类,其中包含一个 SqlConnection 对象。该连接在此类的构造函数中打开,并在其 Dispose 方法中关闭(别误解,我知道保持一个开放的连接是不好的,但这不是我的代码,也不是问题的重点)。Dispose 方法的实现如下所示:
protected virtual void Dispose(bool disposing)
{
    if (!_disposed)
    {
        if (disposing)
        {
            if (_conn != null)
                _conn.Close();
        }

        _disposed = true;
    }
}

问题是:
这是否总是保证连接已关闭?
这段代码正确吗?
我认为应该调用_conn.Dispose() - 我是对的,它会影响不关闭连接吗(可能不会)?

如果你有怀疑,通过使用性能计数器来确认。 - RichardOD
一个需要检查的关键值是NumberOfPooledConnections。 - RichardOD
2个回答

8

Dispose方法不会自动调用。

连接不会关闭,直到显式调用对象的Dispose方法或者在using()块中使用您的类。

更安全的方法是在终结器中调用dispose方法,并确保在调用Dispose方法时抑制终结器。

本文介绍了正确实现该模式的方法。

希望这有所帮助!

Cédric


好的,但如果应用程序被关闭(正常或出现错误),将调用dispose方法并关闭连接? - agnieszka
1
顺便说一下:Dispose方法不会自动调用。在您当前的代码状态下,连接将关闭,因为它们的终结器中调用了Connection的Dispose方法。 - Cédric Rup
你的意思是这个方法永远不会被调用吗? - agnieszka
好的,我终于在 MSDN 上读到了相关内容。他们说 Dispose 是用于显式释放资源的,你应该实现 finalizer 来确保资源始终被释放。我之前不知道这一点。谢谢! - agnieszka
@joe:你的意思是这个类不需要finalizer,因为连接将会在数据提供者对象同时被取消引用,所以连接的finalizer会被GC调用,从而关闭连接? - Cédric Rup
显示剩余6条评论

2

conn.Dispose();也会关闭连接,所以最好按照dispose模式更改它。

但这两个方法在功能上是等效的,因此问题必须在其他地方。

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.close.aspx

如果SqlConnection超出范围,它将不会被关闭。因此,您必须通过调用Close或Dispose来显式关闭连接。Close和Dispose在功能上是等效的。如果连接池值Pooling设置为true或yes,则底层连接将返回到连接池中。另一方面,如果Pooling设置为false或no,则与服务器的底层连接将关闭。


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