0

“File 和 Font 是访问非托管资源(在本例中为文件句柄和设备上下文)的托管类型的示例。还有许多其他类型的非托管资源和封装它们的类库类型。所有此类类型都必须实现 IDisposable 接口。如一条规则,当你使用 IDisposable 对象时,你应该在 using 语句中声明和实例化它。” - MSDN

是否存在应使用 USING 语句的此类情况的列表(访问非托管资源(如 FILE 和 FONT,...)的托管类型?

4

5 回答 5

6

任何实现的类型IDisposable,都应该使用using.

更新(回应评论):using应该围绕一个IDisposable类型的实例,假设在更大的范围内不需要它。

于 2009-05-27T13:59:09.640 回答
2

正确的做法是总是using在类型实现接口时使用语句IDisposable,但要知道规则的异常

已知异常

  • 主窗体(Windows 窗体应用程序,因为它由Application类管理)
  • SystemPens.*, SystemBrushes.*(这些静态实例在内部缓存)
  • Icons.*(这些静态实例在内部缓存)
  • Registry.*(这些静态实例在内部缓存)
  • AutoResetEvent, ManualResetEvent(实际上应该被丢弃,但如果你这样做,请非常小心,因为它可能会导致赛车状况)

已知异常列表肯定不完整。

于 2009-05-27T14:12:51.190 回答
2

每当您有一个需要确定性清理的资源时,即您希望它有机会在您完成后立即被“销毁”。

更详细地说,IDisposible 接口主要尝试解决.net 语言中缺少“删除”关键字的问题。因为 CLR 是垃圾回收器,所以您永远不知道对象的终结器(析构器)何时运行。在开始释放托管资源之前,GC 可以随意等待。

然而,许多托管资源包装了底层的有限资源——内存并不是唯一必须分配和释放的东西。如前所述,文件句柄是其中之一。数据库处理另一个 - 有无数的例子。为了避免不一致的清理习惯用法,IDisposible 模式用于说“请释放你的有限资源,我已经完成了它们”。因为它内置在框架中,它通过“使用”获得特殊的语言支持,以帮助确保您永远不会忘记调用 Dispose 方法,从而“泄漏”非托管资源。

这并不意味着所有IDisposible 实现者都应该包含在 using 中 - 如果您保留引用并且将来需要它们,您当然不应该包装它们,因为您会导致底层资源的过早释放。当您完成对象时才调用 Dispose ,因此仅当您知道在 using 范围结束后已完成该对象时才使用“using”。

因此,正如我们所料,具有确定性破坏的语言,例如 C++/CLI,不需要“使用”。非堆 C++/CLI 对象在超出范围时会自动调用其 Dispose 方法,从而模仿模式试图捕获的析构函数行为。

于 2009-05-27T13:58:36.647 回答
2

不,MSDN 文章刚刚告诉您,在使用IDisposable对象时应该考虑使用它。有许多框架类实现IDisposable了 ,您肯定也会定义许多自己的。

于 2009-05-27T13:58:37.347 回答
0

简单的规则是“任何时候你有一个资源应该在使用后立即释放,而不是在未来某个未知的时刻,当垃圾收集器开始释放它时”。

所有有限的资源,基本上是非托管或托管的。文件、网络套接字、数据库连接、注册表句柄,任何不应该无限期地漂浮的东西。

于 2009-05-27T14:22:41.573 回答