GC.SupressFinalizer()是否阻止GC收集托管资源?
如果最终确定器(Destructor)在类中实现,并且从Overriden Dispose()方法调用GC.SupressFinalizer()垃圾收集器是否仍会照顾任何班级可能拥有的托管资源? 让我感到困惑的是Microsofts关于此问题的文档。例如虚拟处理方法中的模式会照顾托管资源以及未管理的资源。默认情况下,如果GC负责托管资源,为什么要这样做? 如果我定义这样的课程:
public class Car
{
string plateNum;
}
并将此类型用作同样处理未管理资源的类中的一种类型,根据Microsofts文档出色地。为此,汽车必须实现IDISPOSABLE接口。汽车只处理托管资源,没有理由在汽车课上这样做,我不知道在那里dispose()甚至会在那里做什么,也许使铂金无效?另外,为什么有人要在班级上仅处理托管资源的班级? 考虑到这一点,为什么托管资源被处置的Virtual Dispose()方法中的代码中有一个部分?
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if(!this.disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if(disposing)
{
// Dispose managed resources.
component.Dispose();
}
// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false,
// only the following code is executed.
CloseHandle(handle);
handle = IntPtr.Zero;
// Note disposing has been done.
disposed = true;
}
}
我能想到的唯一原因是GC.Supressfinalize(对象)告诉GC,它不需要照顾与给出的对象参数有关的任何内容。 但是不应该这样做,因为实施最终化器应意味着实现其实现的对象应仅在最终器队列 处理该对象之后。通过GC,因为应调用用户明确实现的最终方法。 另外,如果定义了最终化器,是否会改变GC收集实例包含的托管资源的方式,或者仅意味着最终器中包含的其他代码将被执行?
If Finalizer (destructor) is implemented in a class and GC.SupressFinalizer() is called from the overriden Dispose() method will the Garbage Collector still take care of any managed resources the instances of that class might have?
What confuses me is Microsofts documentation on this matter. For example the implemenation of IDisposable pattern in the virtual Dispose method takes care of the managed resources as well as the unmanaged. Why is that being done if the GC is taking care of the managed resources by default?
If I define a class like this:
public class Car
{
string plateNum;
}
and use this type as a filed in a class that also deals with unmanaged resources, according to the Microsofts documentation, the proper way to handle the disposal of the objects would be to call Dispose on the Car as well. For one to do so Car has to implement the IDisposable interface. Car is only dealing with the managed resources, there is no reason for doing so in the Car class, I have no idea what Dispose() would even do there, maybe give null to the plateNum? Also why would anyone want to implement IDisposable on the class that deals with the managed resources only?
Having that in mind, why is there a section in the code in the virtual Dispose() method (in the example in the MS documentation) in which managed resources are disposed?
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if(!this.disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if(disposing)
{
// Dispose managed resources.
component.Dispose();
}
// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false,
// only the following code is executed.
CloseHandle(handle);
handle = IntPtr.Zero;
// Note disposing has been done.
disposed = true;
}
}
The only reason that I can think of is that GC.SupressFinalize(Object) is telling to the GC that it doesn't need to take care of anything related to the object argument that is given. But this shouldn't be the case because implementing the finalizer should only mean that the object that implements it should be put on the Finalizer queue only after the object has been dealt with by the GC because the Finalizer method, that is explicitly implemented by the user, should be called.
Also if a finalizer is defined does that change the way the GC collects the managed resources that the instance contains or does it just mean that additional code contained in the finalizer will be executed?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
已经有很多Q+a,所以我给您一个非常实用的答案:您 won' t曾经需要写一个终结器。
摘要:在极少数情况下,您拥有不受管理的资源,请使用Safehandle类使其成为管理资源。
当您仔细检查完整模式时,您会看到,如果没有不受管理的资源,destructor(又称最终器,
〜myClass(){} {}
)代码路径无能为力。实际上,没有抑制()的最终制度非常昂贵,它会将对象的清理延迟到下一个GC。将其数据推广到Gen 1。
使用
虚拟void Dispose(bool)
的完整模式的剩余原因是继承。资源持有类几乎不需要这一点。因此,将其密封,并且您需要(想要)是:当您需要继承时,这就是官方模式。
There are many Q+A about this already on SO so I'll give you a very practical answer: You won't ever need to write a finalizer.
Summary: In the rare case that you have an unmanaged resource, use the SafeHandle class to make it a managed resource.
When you inspect the full pattern carefully you can see that without unmanaged resources the destructor (aka the Finalizer,
~MyClass() {}
) code path does exactly nothing.And actually having that Finalizer without SuppressFinalize() is very expensive, it will delay the cleanup of your object to the next GC. Promoting its data to gen 1.
The remaining reason for the full pattern with
virtual void Dispose(bool)
is inheritance. A resource holding class should almost never need that. So make it sealed and all you need (want) is:And when you need inheritance then this is the official pattern.