SqlCommand 的Dispose似乎不起任何作用! Why???

stg609 2012-12-12 12:01:57
今天无意中发现即使在执行SqlCommand.ExecuteNonQuery()等数据库操作前对SqlCommand对象进行Dispose操作,也不影响Command的执行。既然这样,为什么还要为Command对象提供Dispose方法呢?


//方式一 手动Dispose
SqlCommand cmd = new SqlCommand();
cmd.Connection = new SqlConnection(@"Data Source = .\sqlexpress;Initial Catalog=Master;User Id=sa;Password=1;");
cmd.CommandText = "select * from XXX";
cmd.Dispose(); //终结这个对象

cmd.Connection.Open(); //Connection对象能正常访问
Console.WriteLine(cmd.ExecuteScalar()); //执行正常



//方式二 使用using,Connection在using外定义
SqlConnection conn = new SqlConnection(@"Data Source = .\sqlexpress;Initial Catalog=Master;User Id=sa;Password=1;");

using(SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = "select * from XXX";
} //终结这个对象

conn.Open();//Connection对象能正常访问
Console.WriteLine(cmd.ExecuteScalar()); //执行正常


原以为Command的Dispose会关闭Connection 或者是让Command中的Connection属性不再指向Connection对象,而通过上面的例子,显然并不会有任何影响。

那为什么要提供这个方法呢? 调与不调有什么区别吗?
...全文
442 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
stg609 2012-12-12
  • 打赏
  • 举报
回复
引用 1 楼 sunny906 的回复:
cmd.Dispose(); 对此类非托管的对象,Dispose方法只是通知GC可以回收Command的对象cmd了,至于什么时候回收,时间是不确定的,即不是人为能掌控的,也不是调了Dispose方法就能立即被销毁的
谢谢你的回答。不过,Dispose的目的之一,就是让程序员能够控制对象的生命周期。不然,全都交给GC自己去清理好了。 一般而言,调用Dispose就会立即执行对象的终结操作(直接关闭非托管资源的句柄),时机是可以掌握的。 但如果你不调用Dispose,转而选择让GC自动执行清理工作,那时机就把握不准:它要判断哪些对象是垃圾(没有被根对象引用),检查是否有终结器,然后执行终结操作,期间会因为“代”的关系,推迟垃圾的清理。(此处内容做了简化)
sunny906 2012-12-12
  • 打赏
  • 举报
回复
cmd.Dispose(); 对此类非托管的对象,Dispose方法只是通知GC可以回收Command的对象cmd了,至于什么时候回收,时间是不确定的,即不是人为能掌控的,也不是调了Dispose方法就能立即被销毁的
你的选择B 2012-12-12
  • 打赏
  • 举报
回复
cmd.Dispose(); 只是立即释放又cmd对象所占用的一切非托管资源,当然IDisposable()接口也正是为了对释放非托管资源提供确定的机制,但是cmd本身是对象,是托管资源,它的释放还是要依赖GC来管理,然而这个时间本身就是不确定的啊
qldsrx 2012-12-12
  • 打赏
  • 举报
回复
SqlCommand是非托管资源,调用完 Dispose 后,必须释放对其的所有引用,这样垃圾回收器才能收回其占用的内存。另外数据库连接默认是有缓存的,因此连接对象是可以重用的。
stg609 2012-12-12
  • 打赏
  • 举报
回复
引用 4 楼 bdmh 的回复:
先说第二种,using外的cmd你能访问?除非你还有一个全局的cmd变量
o, sorry typo.

SqlCommand cmd = null;
SqlConnection conn = new SqlConnection(@"Data Source = .\sqlexpress;Initial Catalog=Master;User Id=sa;Password=1;");
 
using(cmd = new SqlCommand())
{
   cmd.Connection = conn;
   cmd.CommandText = "select count(*) from XXX";
} //终结这个对象
 
conn.Open();//Connection对象能正常访问
Console.WriteLine(cmd.ExecuteScalar()); //执行正常
bdmh 2012-12-12
  • 打赏
  • 举报
回复
先说第二种,using外的cmd你能访问?除非你还有一个全局的cmd变量
stg609 2012-12-12
  • 打赏
  • 举报
回复
趁下班前,再来顶顶~

110,537

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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