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

时间:2008-11-25 12:33:08

标签: c# dispose

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

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

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

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

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

由于

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

安德鲁

3 个答案:

答案 0 :(得分:21)

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

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

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

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

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

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

Dispose调用GC.SuppressFinalize

答案 1 :(得分:5)

  

“IDisisposss不会被处置掉   他们超出了范围?“

没有。如果IDisposable对象是 finalizable ,这不是一回事,那么它将在收集垃圾时完成。

可能很快或几乎不会。

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

  

我只需要使用USING   object使用Dispose来整理   自己了?

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

答案 2 :(得分:2)

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

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