C#USING关键字 – 何时何地不使用它?

我想知道什么时候应该而且不应该在USING块中包装东西。

根据我的理解,编译器将其转换为try / finally,最后在对象上调用Dispose()。

我总是使用围绕数据库连接和文件访问的USING,但它更多的出于习惯而不是100%的理解。 我知道你应该明确(或使用)Dispose()控制资源的对象,以确保它们立即释放,而不是在CLR感觉到它的时候释放,但这就是我理解失败的地方。

IDisposables在超出范围时是否被弃置?

当我的对象使用Dispose来整理自己时,我只需要使用USING吗?

谢谢

编辑:我知道USING关键字上还有其他一些post,但我对CLR的相关答案更感兴趣,而且内部发生了什么

安德鲁

不, IDisposable项目超出范围时不会被处置。 正是由于这个原因,我们需要IDisposable – 用于确定性清理。

他们最终会收集垃圾,如果有终结器,它(可能)会被调用 – 但这可能是将来很长一段时间(不适合连接池等)。 垃圾收集取决于内存压力 – 如果不需要额外的内存,则无需运行GC循环。

有趣的是(也许)有些情况下“使用”是一种痛苦 – 当有问题的类有时会在Dispose()上抛出exception时。 WCF是这个的罪犯。 我在这里讨论了这个主题(有一个简单的解决方法)。

基本上 – 如果类实现了IDisposable ,并且您拥有一个实例(即您创建它或其他任何实例),那么确保它被处置是您的工作。 这可能意味着通过“使用”,或者它可能意味着将其传递给承担责任的另一段代码。

我实际上看过类型的调试代码:

 #if DEBUG ~Foo() { // complain loudly that smoebody forgot to dispose... } #endif 

Dispose调用GC.SuppressFinalize

“当IDisisposables超出范围时,它们是不会被处置掉的吗?”

不。如果IDisposable对象是可终结的 ,这不是一回事,那么它将在收集垃圾时完成。

哪个可能很快或几乎从不。

Jeff Richter的C#/ CLR书非常适合所有这些内容,而且框架设计指南书也很有用。

当我的对象使用Dispose来整理自己时,我只需要使用USING吗?

当对象实现IDisposable时,您只能使用’using’。 如果您尝试不这样做,编译器将反对。

要添加到其他答案,只要对象保存除托管内存以外的任何资源,就应该使用(或显式Dispose)。 例如文件,套接字,数据库连接,甚至是GDI绘图句柄。

垃圾收集器最终将最终确定这些对象,但仅限于将来某些未指定的时间。 您不能及时依赖它,并且在此期间您可能已经耗尽了该资源。