我知道这里有很多关于如何使用 using 语句和调用 Dispose() 方法的线程。我已经阅读了其中的大部分主题。

如果我调用 Dispose(),它会调用 Close() 吗?

如果我想使用一个对象(比如 SqlDataReader),但随后在另一个代码块中再次使用它,我不应该调用 Dispose() 吗?这也意味着省略 using 语句。

另外,为了澄清,如果 FileStream 包装 StreamWriter 并且我在 FileStream 上调用 dispose,这将在 StreamWriter 上调用 Flush()、Close() 和 Dispose() (取决于 Dispose() 是否调用 Close()),正确的?同样,如果我对 FileStream 调用 Close,则只会对 FileStream 调用 Flush() 和 Close()。

检查 IL 是否是回答这些有关幕后情况的问题的好方法?

有帮助吗?

解决方案

如果我调用 Dispose(),它会调用 Close() 吗?

呼唤 Dispose 应采取任何所需的操作来处置资源,这应该类似于(如果不相同的话)调用 Close. 。然而,这是一个实现细节,不一定能得到保证(尽管我们可以预期 BCL 遵循此准则)。

如果我想使用一个对象(比如 SqlDataReader),但随后在另一个代码块中再次使用它,我不应该调用 Dispose() 吗?这也意味着省略 using 语句。

如果你想再次使用该对象,你绝对不应该丢弃它。但是,如果您要两次单独访问数据库,通常应该使用两个单独的连接。保留一个通常不是一个好主意 数据读取器 大约比获取所需数据所需的时间要长。

另外,为了澄清,如果 FileStream 包装 StreamWriter 并且我在 FileStream 上调用 dispose,这将在 StreamWriter 上调用 Flush()、Close() 和 Dispose() (取决于 Dispose() 是否调用 Close()),正确的?同样,如果我对 FileStream 调用 Close,则只会对 FileStream 调用 Flush() 和 Close()。

处置包装另一个一次性对象的对象应该调用 Dispose 在内部物体上。呼唤 Close 在一个 FileStream 将调用其 Dispose 方法下好了,所以它也会作用于两个流。

检查 IL 是否是回答这些有关幕后情况的问题的好方法?

检查 IL 肯定能明确回答大部分问题。作为 @富有的 说,您也可以尝试调试自己的 Dispose 实现。当然,在您尝试自己解决问题之前,还可以先阅读 MSDN 文档,如果您不想在 IL 中浪费时间,还可以使用 Reflector。

其他提示

“如果我调用Dispose(),它调用Close()?”

在理论上,它应该。该BCL类都做到这一点,但它是由图书馆作者正确地处理这个问题。如果您使用的是库做得正确,Dispose()方法也应该关闭()和close()将配置() - 调用应该是可以互换的。

“如果我想使用一个对象(比如SqlDataReader的),但随后在另一个代码块再次使用它,我不应该调用Dispose()?这也意味着省略using语句。”

正确。如果使用using语句,它总是调用Dispose()。这将关闭数据读取器的其他块之前可以使用它。

“此外,为澄清,如果一个FileStream被包裹一个StreamWriter和我调用dispose上的FileStream,这将调用Flush(),关闭()和Dispose()(取决于处置()是否调用Close())在StreamWriter的,是吗?同样地,如果我请的FileStream关闭,这样只会调用Flush()和关闭()上的FileStream。“

如果您是缠绕一个StreamWriter一个FileStream,我强烈推荐一贯对待他们。使用单个使用语句与两个成员,因此,它们都在该块的结束处理。这是最安全,最干净的方法。

“正在检查IL的好办法回答关于什么是引擎盖下发生这些问题呢?”

有一种方法 - 尽管一个更加困难的方法。读了MSDN上关于使用和流和文档将解释它简单来说不是试图解析IL。该IL会告诉你到底发生了什么,不过,如果你很好奇。

  

如果我调用Dispose(),它调用Close()?

关闭()和处置()不相同的,如果适当地实施;它只是一个命名的事情。这听起来较为平淡关闭文件,而不是处理它。请参见实施最后确定并处置以清理非托管资源 esspecialy“定制处置方法名”。

  

如果我想使用的对象(说SqlDataReader的),但是然后在另一个代码#再次使用它   块,我不应该调用Dispose()?这也意味着省略使用语句。

是,由于对象被设置在离开使用块。

  

此外,为了澄清,如果一个FileStream被包裹一个StreamWriter和我调用dispose在>的FileStream,这将调用Flush(),关闭()和处置()(取决于是否Dispos()   调用Close上的StreamWriter()),对不对?同样地,如果我请的FileStream关闭,>这只会调用Flush()和关闭()上的FileStream。

有其他方式;一个StreamWriter是基于基础流的关闭的StreamWriter关闭可能是一个FileStream底层流;看到 MSDN 的参考。因此一个单一的使用语句将StreamWriter的是sufficent。

  
    

如果我调用Dispose(),它调用Close()?

  

不一定。我有时会使用反射来检查究竟在关闭发生和处置。

  
    

如果我想在另一个代码块再次使用(......)吧,我不应该调用Dispose()?

  

正确。调用Dispose时,即可大功告成。 但是,这并不意味着你总是想保持你的对象存活很长一段时间 - 你可以有时会创建多个实例(多个using结构)中获益 - 例如你可能婉尽快关闭连接,但随后又创建一个新的,当你需要它。

正如你所说的,有很多的资源,但是我将包括MSDN链接的一些准则:的实施最后确定并处置以清理非托管资源

处置是链接到IDisposable接口和一次性图案的主要方法。

微软调用等关闭的方法()的一个的域特定别名,然后,使该想法。但它仍然是最多的类的实现者,可能有差异,比如能够重新打开与否。但一般你不应该(必须)照顾。

SqlDataReader对象是有点不好的例子,因为您不能重新使用。而这一般为所有其他一次性物品也最好的建议。

调试这比经历的IL代码会从您的IDisposable派生,覆盖无所事事但调用base.[Method Name]()必要的方法,并设定每一个断点一个简单的方法。然后,如果你包裹在使用块派生类中,你会看到这些调用的生命周期。

没有,IDisposable的不需要关闭(),但实施IDispose对象可以是不够好,它包括在Dispose()方法

您应该尽快你有一块你是从数据库获取数据的处理它。不要让读者打开任何的时间比你所需要的。如果你正在做任何的真正的与数据的工作,使用DataAdapter /数据集,而不是阅读。

没有观。检查生成的IL

我尝试移动使用条款上涨,因为我更喜欢使用这种语法。然后使用来自使用块内该资源调用其它块。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top