关于SqlConnection.Close()和Dispose()方法该何时调用

archu 2011-01-05 01:22:57
这是一个老生常谈的问题了,但是看到这里经常会有各种各样的回答。有的说用完之后两个方法最好都调用一下,有的说不调用的话就会导致连接池满,……

总之,似乎并没有统一的标准答案。让我们先看看MSDN吧:http://msdn.microsoft.com/en-us/library/ff647768.aspx

这上面提到的关闭数据库连接的两种标准做法:


public void DoSomeWork()
{
SqlConnection conn = new SqlConnection(connectionString);
…try
{
conn.Open();
// Do Work
}
catch (Exception e)
{
// Handle and log error
}
finally
{
if(null!=conn)
conn.Close();
}
}



using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
. . .
} // Dispose is automatically called on the conn variable here


显而易见,我们并不需要同时调用两个方法,只要调用Close()或者Dispose()中的任意一个就可以了,理由很简单,看看Dispose()的实现就知道了。

/// <summary>
/// Releases all resources used by the <see cref="T:System.ComponentModel.Component" />.
/// </summary>
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}

protected override void Dispose(bool disposing)
{
if (disposing)
{
this._userConnectionOptions = null;
this._poolGroup = null;
this.Close();
}
this.DisposeMe(disposing);
base.Dispose(disposing);
}


也就是说,调了Dispose()方法之后,它会自动调用Close()方法的。其实,对于Close()来说,并不是真正地把数据库连结给关闭了,只是放回到的连接池而已;这一点,很多人会误以为调用了Close()就是把连接关闭了。

那么,如果不调用Dispose()或者Close()又会怎样呢?
当你的程序并不需要频繁地操作数据库的时候,就算忘记调用Dispose或者Close也无伤大雅,因为SqlConnection类实现了Finalize方法,而Finalize方法里面又调用了Dispose。所以,最终Finalizer Queue在回收资源的时候也会调用到SqlConnection的Close()方法的。

其实,关于这一切MSDN上面都说得很清楚:
•Using either the Close method or the Dispose method is sufficient. You do not have to call one method after the other. There is no benefit to calling one method after the other.
•Dispose internally calls Close. In addition, Dispose clears the connection string.
•If you do not call Dispose or Close, and if you do not use the using statement, you are reliant upon the finalization of the inner object to free the physical connection.
•Use the using statement, instead of Dispose or Close, when you are working with a single type, and you are coding in Visual C#®. Dispose is automatically called for you when you use the using statement, even when an exception occurs.
•If you do not use the using statement, close connections inside a finally block. Code in the finally block always runs, regardless of whether an exception occurs.
•You do not have to set the SqlConnection reference to null or Nothing because there is no complex object graph. Setting object references to null or to Nothing is usually done to make a graph of objects unreachable.

...全文
1288 38 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
close和dispose可以同时使用吗,会有问题吗
anbin0814 2011-01-21
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 archu 的回复:]
引用 31 楼 anbin0814 的回复:

推荐使用try、 catch conn.Close()
这样可以扑捉异常,
用using没有办法扑捉异常,而且用using 必须的实现IDisposible接口 运行完成后他会把连接释放,下次需要重新连接


这位同学,你千万不要误导人家啊。你的前半部分关于“不能捕捉异常”是正确的,至于后面的“把连接释放,下次需要重新连接”就是完全错误……
[/Quote]

我只弄过连接关闭,没用过连接释放
anbin0814 2011-01-20
  • 打赏
  • 举报
回复
推荐使用try、 catch conn.Close()
这样可以扑捉异常,
用using没有办法扑捉异常,而且用using 必须的实现IDisposible接口 运行完成后他会把连接释放,下次需要重新连接
Crossgate_J 2011-01-20
  • 打赏
  • 举报
回复
SqlConnection.Close();
apple130 2011-01-20
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 jiangqixian 的回复:]
OK

引用 14 楼 subxli 的回复:
也就是说,调了Dispose()方法之后,它会自动调用Close()方法的。其实,对于Close()来说,并不是真正地把数据库连结给关闭了,只是放回到的连接池而已;这一点,很多人会误以为调用了Close()就是把连接关闭了。
[/Quote]

学习~
  • 打赏
  • 举报
回复
有啊!
C5662601 2011-01-20
  • 打赏
  • 举报
回复
除了DataReader需要关闭 其它都不用考虑
roseorgun 2011-01-20
  • 打赏
  • 举报
回复
我也一般用USING的
archu 2011-01-20
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 anbin0814 的回复:]

推荐使用try、 catch conn.Close()
这样可以扑捉异常,
用using没有办法扑捉异常,而且用using 必须的实现IDisposible接口 运行完成后他会把连接释放,下次需要重新连接
[/Quote]

这位同学,你千万不要误导人家啊。你的前半部分关于“不能捕捉异常”是正确的,至于后面的“把连接释放,下次需要重新连接”就是完全错误的了。

用了using之后,相当于以下的代码

SqlConnection conn = new SqlConnection(connString);
try
{
conn.Open();
}
finally
{
conn.Dispose();
}


最终会调用到Dispose()方法。对于SqlConnection来讲,调用Dispose或者Close的本质是差不多的,最终都是把连接返回到连接池里面。

请你仔细阅读并理解内部原理之后再发表高见,呵呵。
archu 2011-01-19
  • 打赏
  • 举报
回复
还有要分的吗?
笨熊熊 2011-01-07
  • 打赏
  • 举报
回复
現在要麽就用Using
要麽就close();dispose();
sshenry1151 2011-01-07
  • 打赏
  • 举报
回复
养成好习惯,使用完后CLOSE掉啊!
julian 2011-01-05
  • 打赏
  • 举报
回复
OK
[Quote=引用 14 楼 subxli 的回复:]
也就是说,调了Dispose()方法之后,它会自动调用Close()方法的。其实,对于Close()来说,并不是真正地把数据库连结给关闭了,只是放回到的连接池而已;这一点,很多人会误以为调用了Close()就是把连接关闭了。
[/Quote]
阿非 2011-01-05
  • 打赏
  • 举报
回复
你想说明什么?
newdigitime 2011-01-05
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 wanzhengcheng 的回复:]
<script>alert('123');</script>

我要看看这句话会被弹窗不
[/Quote]
太无视CSDN技术员了.弹你JJ
wanzhengcheng 2011-01-05
  • 打赏
  • 举报
回复
<script>alert('123');</script>

我要看看这句话会被弹窗不
newdigitime 2011-01-05
  • 打赏
  • 举报
回复
我也一般用using
或者 conn.Close();

微软自己的代码就这样写了,大家还怕什么.
subxli 2011-01-05
  • 打赏
  • 举报
回复
也就是说,调了Dispose()方法之后,它会自动调用Close()方法的。其实,对于Close()来说,并不是真正地把数据库连结给关闭了,只是放回到的连接池而已;这一点,很多人会误以为调用了Close()就是把连接关闭了。
xuan.ye 2011-01-05
  • 打赏
  • 举报
回复
活到老,学到老

长知识了
萤火架构 2011-01-05
  • 打赏
  • 举报
回复
最好是明确的写上
加载更多回复(2)

62,243

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧