gpt4 book ai didi

c# - 是否有可能在实现 IDisposable 的类的析构函数中调用 GC?

转载 作者:太空宇宙 更新时间:2023-11-03 20:10:26 25 4
gpt4 key购买 nike

------------编辑1------------

对不起,我的英语不好,似乎原来的问题对很多人来说都没有意义,所以我把问题大大简化为两句话:

IDisposable pattern in MSDN 的 msdn 代码示例中, 将释放非托管资源代码放在析构函数中是为了当用户忘记调用Dispose() 释放资源时,GC 仍然可以帮助释放至少非托管资源,但是,当一个类使用一些非托管资源时,它必须(隐式或显式)将当前实例(或字段)注册到 GC 句柄表,然后永远不会被 GC,那么在这种情况下如何执行析构函数中的代码?

------------结束Edit1--------

我们知道著名的 IDisposable 模式,它可以在网络上看到很多,例如:IDisposable pattern in MSDN

在示例中,据我了解,析构函数的目的适用于这种情况:如果用户忘记显式调用 Dispose(),则 GC 将提供帮助 并释放未-托管资源。

但我只是想知道,在任何情况下,GC 都可以调用析构函数而无需用户代码先显式调用Dispose()

猜测是基于实现 IDisposable 的原因,并且有一个显式析构函数:

此类使用了一些非托管资源。无论是通过 P/Invoke 还是托管 API (BCL),据我所知,这两种方式都需要向 GC 句柄表添加一个GC 句柄条目,以避免 GC,因此析构函数永远不会被 GC 调用。

所以我们永远不应该指望资源自动释放的运气?为什么要将其放入示例代码中?

最佳答案

这里有很多问题。让我们试着回答所有这些问题。

In the MSDN code sample of the IDisposable pattern code to release unmanaged resources is put in the destructor. This ensure that when a user forgots to call Dispose() to release the resource, the GC still releases the unmanaged resources.

正确。

But when a class uses some unmanaged resources, it must have registered the current instance to GC handle table and then would never be GCed.

这句话我没看懂。您所说的“GC 句柄表”是什么?

您能否展示一些示例代码来演示您的场景?

How does the code in destructor get executed in this situation?

简而言之,GC 是这样工作的。 GC 知道“根”;这些绝对是活生生的引用资料。 GC 首先将所有对象标记为已死亡。然后它将根标记为活着。然后它将根标记为事件的所有内容,然后它们 标记为事件的所有内容,依此类推。那就是从根可以到达的一切都是活的。然后 GC 杀死所有仍然标记为死的东西。

现在,如果死对象是可终结的——如果它有一个尚未运行的析构函数——那么 GC 不会杀死该对象。对象被放到一个要终结的对象列表中,这个列表是一个根,所以对象又活了。稍后,另一个线程运行终结队列中每个对象的析构函数,并将它们从队列中移除,并将它们标记为不再需要终结。

下次 GC 运行时,如果对象仍然是死的,那么它会被收集并且终结器不会再次运行。

Can the destructor get called by the GC without user code explicitly call Dispose() first?

是的。这就是析构函数的重点。

关于c# - 是否有可能在实现 IDisposable 的类的析构函数中调用 GC?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20463390/

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