gpt4 book ai didi

.net - 在托管环境中为什么我们需要 IDisposable

转载 作者:行者123 更新时间:2023-12-02 22:22:24 24 4
gpt4 key购买 nike

托管代码的主要优点之一是内置内存管理。您不需要跟踪指针、缓冲区大小、释放内存等,托管 方面会为您完成这些。

那么为什么我们有一个IDisposable接口(interface)呢? MSDN says该接口(interface)用于处理非托管资源,如窗口句柄、文件等。但为什么要求我显式调用 Dispose 方法(或使用 Using)?

  1. 为什么当对象超出范围时 CLR 不能跟踪并自动调用 Dispose
Public Function DoSomething() As String
Dim reader As New StreamReader("myfile.txt")
Dim txtFromFile As String = reader.ReadToEnd()

Return txtFromFile '<==== reader goes out of scope after this line, so call Dispose automatically
End Function
  1. 至少,垃圾收集器为什么不最终找到它并调用 Dispose

我错过了什么?

编辑

有几个人(在这里和其他建议使用的答案)建议垃圾收集不够好,因为 GC 只是最终开始收集ID 一次性。我不明白为什么该参数会区分 IDisposable 和 .NET 中的任何其他对象。在您说 IDisposable 对象需要更多资源之前,请考虑:

  1. MSDN从上面说 IDisposable 用于非托管对象,无论它们的资源需求如何
  2. 我见过一些非常占用资源的 .NET 对象(System.Web.UI.PageSystem.Data.Objects.ObjectContext 怎么样)。

最佳答案

正如我在评论中所说,CLR 不会跟踪对象何时超出范围。

让我们举个例子:

Public Function DoSomething() As String
Dim reader As New StreamReader("myfile.txt")
Dim txtFromFile As String = reader.ReadToEnd()

Return txtFromFile '<==== reader goes out of scope after this line, so call Dispose automatically
End Function

实际需要的是它分析方法的整个主体,检查您是否已将对此读取器的引用传递给另一个方法,或者是否将引用存储在某个字段中。

然后需要确定其他方法是否已将引用存储在某处,或调用其他方法等。

然后必须推断,如果引用存储在其他任何地方,其意图是否是其他东西稍后会使用该引用并期望找到一个非-在那里处置实例。

将其与的知识进行比较。您知道(希望如此)您是否在别处存储了引用,或者将引用传递给了“拥有”此一次性用品的其他对象。如果您知道这两种情况都没有发生,您可以将此知识传达给编译器 - 通过添加 Using block 。


Or in any event, won't the garbage collector eventually get to it and call Dispose?

如果 a) 对象直接“包含”非托管资源,并且 b) 实现此对象的人遵循最佳实践,那么他们应该在此对象上实现一个终结器,该终结器将对非托管资源执行清理(通常通过调用终结器和 Dispose 之间共享的方法。

但是,您不知道下一次垃圾收集何时发生。与此同时,您可能会拒绝其他程序访问相同的非托管资源——甚至是您自己程序的另一部分。您应该将非托管资源视为稀缺资源。如果有人实现了 Dispose,他们希望您在知道不再需要访问该资源时调用它(明确地或通过 Using)。

关于.net - 在托管环境中为什么我们需要 IDisposable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13488112/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com