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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/317184/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 22:57:53  来源:igfitidea点击:

C# USING keyword - when and when not to use it?

c#dispose

提问by Andrew Bullock

I'd like to know when i should and shouldn't be wrapping things in a USING block.

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

From what I understand, the compiler translates it into a try/finally, where the finally calls Dispose() on the object.

据我了解,编译器将其转换为 try/finally,其中 finally 对对象调用 Dispose()。

I always use a USING around database connections and file access, but its more out of habit rather than a 100% understanding. I know you should explicity (or with a using) Dispose() objects which control resources, to ensure they are released instantly rather than whenever the CLR feels like it, but thats where my understanding breaks down.

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

Are IDisposables not disposed of when they go out of scope?

IDisposables 超出范围时是否不会处理?

Do I only need to use a USING when my object makes use of Dispose to tidy itself up?

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

Thanks

谢谢

Edit: I know there are a couple of other posts on the USING keyword, but I'm more interested in answers relating the the CLR and exactly whats going on internally

编辑:我知道还有一些关于 USING 关键字的其他帖子,但我对与 CLR 相关的答案以及内部发生的事情更感兴趣

Andrew

安德鲁

采纳答案by Marc Gravell

No, IDisposableitems are not disposed when they go out of scope. It is for precisely this reason that we need IDisposable- for deterministic cleanup.

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

They will eventuallyget garbage collected, and if there is a finalizer it will (maybe) be called - but that could be a long time in the future (not good for connection pools etc). Garbage collection is dependent on memory pressure - if nothing wants extra memory, there is no need to run a GC cycle.

他们最终会被垃圾收集,如果有一个终结器,它会(可能)被调用——但这可能会在未来很长一段时间(对连接池等不利)。垃圾回收依赖于内存压力——如果没有什么需要额外的内存,就没有必要运行一个 GC 循环。

Interestingly (perhaps) there are some cases where "using" is a pain - when the offending class throws an exception on Dispose()sometimes. WCF is an offender of this. I have discussed this topic (with a simple workaround) here.

有趣的是(也许)在某些情况下“使用”是一种痛苦 - 当有问题的类Dispose()有时会抛出异常时。WCF 违反了这一规定。我已经讨论过这个话题(用一个简单的解决方法)在这里

Basically - if the class implements IDisposable, and you ownan instance (i.e. you created it or whatever), it is your job to ensure that it gets disposed. That might mean via "using", or it might mean passing it to another piece of code that assumes responsibility.

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

I've actually seen debug code of the type:

我实际上已经看到了以下类型的调试代码:

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

(where the Disposecalls GC.SuppressFinalize)

(那里的Dispose电话GC.SuppressFinalize

回答by Will Dean

"Are IDisposables not disposed of when they go out of scope?"

“当 IDisposables 超出范围时,它们不会被处理掉吗?”

No. If the IDisposable object is finalizable, which is not the same thing, then it will be finalized when it's garbage collected.

不。如果 IDisposable 对象是finalizable,这不是一回事,那么它会在垃圾回收时被终结。

Which might be soon or might be almost never.

这可能很快,也可能几乎永远不会。

Jeff Richter's C#/CLR book is very good on all this stuff, and the Framework Design Guidelines book is also useful.

Jeff Richter 的 C#/CLR 一书在所有这些方面都非常好,框架设计指南一书也很有用。

Do I only need to use a USING when my object makes use of Dispose to tidy itself up?

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

You can onlyuse 'using' when the object implements IDisposable. The compiler will object if you try to do otherwise.

只能在对象实现 IDisposable 时使用“使用”。如果您尝试其他方式,编译器将反对。

回答by babbageclunk

To add to the other answers, you should use using(or an explicit Dispose) whenever an object holds any resources other than managed memory. Examples would be things like files, sockets, database connections, or even GDI drawing handles.

要添加到其他答案中,您应该using在对象拥有托管内存以外的任何资源时使用(或显式 Dispose)。例如文件、套接字、数据库连接,甚至 GDI 绘图句柄。

The garbage collector would eventually finalise these objects, but only at some unspecified time in the future. You can't rely on it happening in a timely fashion, and you might have run out of that resource in the meantime.

垃圾收集器最终会终结这些对象,但只会在未来某个未指定的时间完成。您不能指望它及时发生,并且在此期间您可能已经用完了该资源。