【发布时间】:2009-02-24 17:02:26
【问题描述】:
每次我询问开发人员时,我似乎都会得到不同的答案。所以我认为溢出来看看每个人都做了什么是一个很好的问题。
如果你有一个 sqlClient.sqlconnection 对象,在清理代码中(最终阻塞等)你是处置该对象还是将其设置为空,或两者兼而有之?
我一直只是调用 dispose,并允许垃圾收集器做它的事情...
【问题讨论】:
每次我询问开发人员时,我似乎都会得到不同的答案。所以我认为溢出来看看每个人都做了什么是一个很好的问题。
如果你有一个 sqlClient.sqlconnection 对象,在清理代码中(最终阻塞等)你是处置该对象还是将其设置为空,或两者兼而有之?
我一直只是调用 dispose,并允许垃圾收集器做它的事情...
【问题讨论】:
看看my answer to a similar question。很少需要将变量设置为 null/Nothing。调用 Dispose 是必要的。
【讨论】:
你基本上做对了。调用 .Dispose() 后,可以确保连接分配的资源被清理干净。然后,一旦您在代码中声明的 SqlConnection 对象超出范围,GC 也会清理该内存。
如果你想激发 GC,你可以随时调用它的 .Collect() 方法。
【讨论】:
你不需要将变量设置为Nothing,只需disposing就足够了。
【讨论】:
Jeff Atwood 对此有一个 recent blog post...
除非您不信任垃圾收集器,否则似乎没有必要。我已经完全停止这样做,并且最常使用简洁且易于理解的“使用”语法。
【讨论】:
如果您在反射器中使用“= Nothing”打开代码,您将看到编译器(通常)已删除/优化了该语句。
现在,如果您进行这样的检查。
If myObject IsNot Nothing Then
myObject = Nothing
End If
编译器可能不会对此进行优化,这将导致您持有对 myObject 的引用超过必要的时间,从而导致对象等待的时间超过了获得 GC 资格所需的时间。
理想情况下,您应该尽快处理该对象并让它不理会。
【讨论】:
如果类型有 Dispose 使用它。
如果该类型没有 Dispose,并且它持有大量内存,那么在执行一些缓慢的操作之前将引用设置为空(而不是持有它)可以帮助避免“中年危机”。
但是编译器在优化这种情况并在块结束之前释放引用方面变得更好。
【讨论】:
我总是确保通过使用“使用”块来处理它们,但从不将它们设置为 null。 MSDN 也没有要求我们这样做。
我很乐意了解其他人必须将 ref 显式设置为 null 的任何原因。 在处置后使用该对象无论如何都会引发“ObjectDisposedException”,因此处置后的意外使用不能成为原因。
【讨论】:
我同意,只要对象实现了 dispose() 方法,就必须调用它,因为当某些对象实现 dispose() 方法时,这意味着他不能指望 GC 来释放在这种情况下,他一直在使用的资源(即他正在使用非托管资源),是的,您必须调用 dispose 才能释放这些非托管资源。关于设置对 null 的引用,这不是必需的,但毫无疑问它仍然是一个很好的编程习惯。这里真正有趣的是,任何人都可以使用已处置的对象或没有引用的对象(即死(或者更确切地说即将死)的对象可以复活吗? 请看以下内容:
公共类员工{
public static Employee emp;
public string Name { get; set; }
public string Position { get; set; }
public override string ToString() {
return String.Format("{0} works as {1}", Name, Position);
}
~Employee() {
emp = this;
}
}
【讨论】: