【发布时间】:2011-10-11 21:19:32
【问题描述】:
我是否必须使用using 语句才能立即处置,即使在方法中?或者该方法的结束会导致包括图形在内的所有局部变量的自动Dispose?
(我问这个是因为我看到在方法末尾有 Dispose 调用的示例,并且想知道这是否真的有必要。)
谢谢。
【问题讨论】:
标签: c# garbage-collection dispose using
我是否必须使用using 语句才能立即处置,即使在方法中?或者该方法的结束会导致包括图形在内的所有局部变量的自动Dispose?
(我问这个是因为我看到在方法末尾有 Dispose 调用的示例,并且想知道这是否真的有必要。)
谢谢。
【问题讨论】:
标签: c# garbage-collection dispose using
是的,你知道。超出范围不会做任何事情;它不调用Dispose(),不进行垃圾收集,也不调用终结器。
如果类型是IDisposable,则是。您的工作是自己整理(假设此时对象实际上已“完成”)。
不这样做的可能副作用:
FileStream)DbConnection)TransactionScope / DbTransaction)基本上是坏事。
此外,在大多数情况下,如果您在方法底部看到Dispose(),则最好使用using。 在某些情况下这是不可能的(例如,对象上的字段),但重点仍然存在:听起来这些都是不好的例子。
【讨论】:
Dispose 以获得 Graphics - 内存不会立即被 GC,只有当 GC 进行循环时?
你从来没有有去处理一个对象。但是,如果您想更早地释放非托管资源,而不是在 GC 处理它时(即它处理 fReachable 队列时),那么 是的,您应该,因为方法的范围不能确定何时将调用一次性对象的 finalize。
您可能想阅读 Jeffrey Richter 的 Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework 了解更多信息
正如 delnan 指出的那样,如果您使用的资源存在硬性限制,那么如果您让 GC 回收而不是调用 Dispose,您更有可能受到影响。数据库连接是这种资源的一个很好的例子,当然也是创建NumberOfReclaimedConnections 性能计数器的原因。
【讨论】:
Dispose 调用,则您会泄漏。如果在此之后没有偶然调用终结器,则您会泄漏(可能很长时间)一段时间。如果一个人可以同时打开的此类资源的数量存在硬性限制,并且您要打开的此类资源的数量也差不多,那么如果您不处置,您很容易用完它们。
Dispose,您最终可能会遇到托管内存仍然很空,但非托管资源已耗尽的情况。所以请尽快致电Dispose。一旦您不需要已定义该方法的对象,请调用它。
Dispose(true) 应该只在其他托管对象上调用 Dispose。如果终结器正在运行,则 GC 当前正在处理 fReachable 队列。这意味着此时也会清理任何引用的非托管资源(这比我们想要的要晚)。只是不是通过 Dispose
是的,使用using。这是一个很棒的声明。
实际上,如果您不调用Dispose(手动或使用using),您最终可能会遇到托管内存仍然很空,但非托管资源已耗尽的情况。最终它可能会导致死锁,因为其他对象或其他进程将等待您的非托管资源,而您将等待它们。 (垃圾收集器不会运行,因为托管内存仍然不会满。)
所以请尽快致电Dispose。一旦您不需要已定义该方法的对象,请调用它。
【讨论】: