|
|
1
7
那篇博文的作者有点困惑… 在C中,没有“析构函数”这样的东西。仅限终结器和IDisposable。 ~classname()方法不被称为“析构函数”。它被称为终结器。 Dispose存在以释放代码中的资源,其中存在要从GC调用的终结器。通常,终结器调用Dispose()方法,但 "Dispose Pattern" 设置为仅处理来自终结器的非托管资源。 您可以看到,当调用终结器时,您处于不同的线程上,并且您拥有的任何托管对象都不一定有效。因此,如果从终结器调用Dispose(),则实际上应该调用Dispose(false),它告诉“Dispose模式”只释放非托管资源。 此外, “释放模式” 建议在调用Dispose(true)时,应取消该对象上的终结器。 |
|
|
2
4
只有托管对象才能自动完成。如果你想提供 隐性的 处理非托管对象时,可以使用终结器。如果你想提供 明确的 控制对象的调用方的释放,您可以允许他们调用释放。 |
|
|
3
3
很难回答这个问题,因为你已经链接到解释差异的文章。 但无论如何让我试试。 对于垃圾收集,您有不确定的内存管理,并且由于GC将运行终结器,所以您有保证,但不确定的资源管理。 这很好,从某种意义上说,你知道事情会被清理干净。 但是,这很糟糕,因为你不知道什么时候会发生。 例如,如果您打开一个文件并在打开时将其锁定,不知道该文件什么时候以后可以再次打开是不好的,但是保证在某个时刻它将被关闭是很好的。 Dispose和IDisposable通过添加确定性资源管理来解决这个问题。您可以选择何时释放资源、关闭文件、网络连接、数据库连接等。这是您的选择,当您不再需要资源时,您通常会将其丢弃。因此,当您不再需要该文件时,您将处理保持其打开的对象。对象将在内存(非确定性内存管理)中停留一段时间,但当您这样说时,文件将被关闭,准备立即再次打开。 因此,您获得了对资源的确定性处理,并将其与非确定性内存管理结合起来,就得到了两个世界中最好的。 |
|
|
4
2
C中的析构函数是什么样子的?#(
也许事后看来,语法的选择不是最好的,因为
|
|
|
5
2
很抱歉回答我自己的问题,但我认为我收集了各种来源的答案,其中包括一些答案是我的问题的一个简明答案,解决了在转换到GC平台时对象生命周期的差异。 非GC对象生命周期: 初始化: 在将第一个引用添加到对象时调用的构造函数中发生。 Cleanup: 在析构函数中发生,该析构函数在最后一个引用对象的变量超出范围或显式设置为Nothing/null/其他对象时调用。 GC对象生命周期: 初始化: 在将第一个引用添加到对象时调用的构造函数中发生。 清理(第一遍): 在Dispose方法中发生,该方法必须由客户端显式调用或在using语句结尾隐式调用。这种清理专门用于释放必须立即释放的资源,而不是等待GC。 清理(最终通过): 发生在finalize方法中,该方法在GC的时间表上调用,可以延迟。如果实现了Finalize方法,则除非以前对对象(通常从Dispose方法中)调用了gc.SuppressFinalize以将其标记为已清除,否则将调用该方法。 我说得对吗?如果我错过了什么,请随意编辑。 |
|
|
6
1
C不提供析构函数,所以您的问题有点无意义? |
|
|
7
1
我不确定析构函数和终结器之间的推理,但存在Dispose,以便在垃圾收集器到达对象之前释放资源(可能永远不会!) |
|
|
8
1
等待终结器运行以释放资源的问题是,它不会以可预测的确定性方式运行。当GC准备销毁对象时调用终结器,这可以在应用程序中的任何时候发生。 这就是为什么你要处理。它允许您在已知的时间点确定性地释放资源,确保资源将被释放。否则,您将无法控制终结器何时运行。 |
|
|
9
1
Finalize无法访问托管对象,因此应在Dispose中处理托管对象。这两者之间的区别在于,应使用Dispose for Managed和Finalize for Unmanaged。析构函数应该调用Dispose,以便正确地清除内存。请看以下文章: Code Project - IDisposable: What Your Mother Never Told You About Resource Deallocation Gil Fink - Memory Leak And The IDisposable Pattern |