[已解决问题] 关于对象生命周期的一个小问题
提问时间: 2008-04-22 12:55
悬赏分:5 浏览:267 次

大家好。如下面的代码:

public class Test {
    public void Method() {
        SqlConnection conn = new SqlConnection(connStr); 
        //...方法体中没有显式关闭conn
    }
}

对于这里的conn,我的理解是:调用Method()方法时,当执行到方法的最后一个}时,conn变量的作用域已到,所以栈上的conn变量值被释放,但是托管堆中的conn对象仍然存在,它要等待垃圾回收器的清理,这样说对么?

所以如果要在此返回一个SqlDataReader对象的话,必须要cmd.ExecuteReader(CommandBehavior.CloseConnection),因为这么做的话,当返回的DataReader对象在另外的地方被关闭时,这个conn也自动被关闭了,对么?

提问者:水言木 - 菜鸟二级
最佳答案
严格的说法是: 调用堆栈是GC的根对象,而这个例子中的调用堆栈中包含到Connection的引用(而不是Connection对象,如果你要理解这里的策略,一定要很好的理解引用和对象的区别),因此,在这个方法中,如果触发了GC的回收动作,GC不会回收Connection对象。 同时,Connection对象应该实现了Disposable模式(或者继承自SafeHandle),在Finalize方法中调用了自己的Close方法。 因此,如果你不显示的调用Connection的Close方法或Dispose方法时,它将会被GC的Finalize线程回收。这种回收是不可靠的,并且可能产生性能问题,因此,建议你使用楼上的写法。 另外,SqlDataReader关闭时关闭Connection对象的做法,个人感觉是微软.NET目前的机制不能很好的平衡这一点,因此为了照顾易用性,而损失了逻辑严密性的一个做法。建议不要追究它的逻辑是否严密了。你就认为这时候,Reader的Close方法在调用它自己抓着的Connection对象上的Close方法就可以了。
2008/4/22 13:25:22 回答者:Colin Han


提问者对于答案的评价:恩,谢谢。 不过如果要返回SqlDataReader的话,就没办法用 using (SqlConnection conn = new SqlConnection(...)) { //... } 了,否则返回的SqlDataReader都是已关闭的,不能用。
其它回答(2)
对。
5个月前   回答者:deerchao - 大侠五级
using(SqlConnection conn = new SqlConnection(_connectionString)){ PrepareCommand(cmd, conn, null, cmdType, cmdText, cmdParms); int val = cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); return val; } 你说的第一点 我想应该是这样的吧! 但是后面说的就有点问题了
5个月前   回答者:yeyang - 菜鸟二级
评论
   您需要登录以后才能回答!
 

我要提问

我的问题


快到期问题

> 问题排行榜

相关内容

相关链接