在C#中什么时候应该使用"using"块?

75

在使用“using”块时,有哪些特定情况应该(或不应该)使用:

using(SomeType t = new SomeType()){
    ...
}

4
为什么这是一个社区维基? - JaredPar
1
@JaredPar,我也不明白。无论如何,这是他选择不分配声望的决定。 =[ - strager
重复的问题,已经被问过很多次了。 - George Stocker
1
@JaredPar;有争议和主观性。从人到人之间使用using声明的方式似乎存在很大差异。 - jay_t55
14个回答

1
也许值得一提的是,添加“using”到C#语言中的根本原因是:有些资源可能非常稀缺,以至于等待GC调用IDisposable就没有意义了。例如,数据库连接。如果您使用try/catch/finally,您不会遇到悬空连接,但连接将保持挂起状态,直到GC启动,这可能需要一段时间(如果您没有显式关闭它)。如果您使用“using”(请原谅双关语),即使您忘记关闭它,甚至在using块内发生异常,您也会立即释放连接。
另一个原因,正如先前的帖子所提到的,是程序员并不总是使用finally来清理。如果在异常情况下不使用finally,则会导致资源泄漏...

0

其他人已经提到了"IDisposable"。

但是使用"using"语句时的一个注意事项是, 任何在"using"内抛出的异常都不会被捕获, 尽管"SomeType"将会被处理掉。

因此,在下面的代码片段中,

using (SomeType t = new SomeType()){
    throw new Exception("thrown within using");
}

throw new Exception("thrown within using");不应该被忽视。


异常被使用C# catch关键字声明的catch处理程序捕获。'using'对此没有影响。如果有适当的'catch'处理程序,'using'中抛出的异常将会被捕获。 - Scott Langham
3
哦,我明白了。你的意思是 'using' 会确保即使在使用过程中抛出异常,Dispose 方法也会被调用以释放 't'。 - Scott Langham
是的,Scott。那正是我的观点。 - dance2die

0
一种情况是当你想在代码块的开始做某些事情,然后在代码块结束时无条件地撤销它(即使有异常抛出)。
你构建的可释放类的构造函数(并在using语句中调用)会执行这个操作,然后Dispose方法会撤销该操作。这通常是我使用它的方式。

这听起来像是下一个需要处理那段代码的开发人员将会遇到很多混乱。为什么不使用一个(更标准的)“finally”块呢? - AwesomeTown
使用log4net时,以下代码会将字符串推入NDC栈中: using (NDC.Push("string")) 第一次调用会将字符串推入栈中,而dispose方法则会将该项从NDC栈中弹出。 - Allen Rice

0

我还要补充一点,如果某个东西实现了IDispose接口,并且你想要处理它所持有的非托管资源,比如数据库连接和文件句柄,那么使用using()语句是很好的选择。

如果它只是一个普通对象,例如一个包含名称和地址的Customer对象的List<T>,那么你就不需要这样做。垃圾回收器足够聪明,可以为你管理这些对象。但是垃圾回收器不会将连接返回到连接池或关闭文件句柄。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接