Why do I need a finalizer if my class implements IDisposable?

丶灬走出姿态 提交于 2020-01-14 18:59:09

问题


What about below disposable pattern?

using System;
public class MyClass : IDisposable 
{     
    public void Dispose() 
        // Implement IDisposable     
    {
        //just do the cleanup
        GC.SuppressFinalize(this);
    } 

} 

Sorry for confustion. I meant to say, if there are no un-managed resources do i need finalizer? isnt the above disposable pattern is good enough? Yes, even though users/develoeprs doesnt invoke dispose, doesnt GC invoke dispose by default?

And what about the order in which GC invokes dispose and finalizers?

Please see standard dispose pattern? why do we need "disposing" parameter in the virtual method and isn't the finalizer get called after dipose always? for more details.

In other when we have finalizer, why do we call Dispose with false as parameter.


From http://msdn.microsoft.com/en-us/magazine/cc163392.aspx#S2, looks like its always advisable to release unamaged resources from finalizer and not the managed references.

Its always recommended to release unamaged resources from Dispose method...

Still didnt get total gist though and reading the article.

but if there are no unmaged resources, the below pattern shoudl work...

according to msdn.microsoft.com/en-us/magazine/cc163392.aspx#S2, msdn.microsoft.com/en-us/library/fs2xkftw.aspx its recommended to release native resources in finalizer and all of them with dispose(). if dispose() is called explicitely, it can suppress finalizer.i.e; if there no native reosurces, we dont need fianlizer.

using System;
public class MyClass : IDisposable 
{ 
    private bool disposed = false;  
    protected virtual void Dispose(bool suppressFinalize) 
    {    
        if (!disposed)
        {
            //Just do the cleanup
            //and release resources
            disposed = true; 
        }
        if (!suppressFinalize)
        {
            GC.SuppressFinalize(this); 
        }
    }
    public void Dispose() 
        // Implement IDisposable     
    {
        Dispose(true);           
    } 
    ~MyClass() // the finalizer
    {     
        Dispose(false);    
    }
} 

regards, dreamer


回答1:


Because you might have direct references to unmanaged resources (e.g. Windows handles) and you want to release them even if no-one calls Dispose.

This is very rare though - usually you only really have indirect references to unmanaged resources, via other managed types which will have finalizers if they need them.




回答2:


Finalization + IDisposable in .Net is really two distinct problems which are attempted to be solved with the single disposable pattern.

  • Managed resource cleanup
  • Unmanaged resource cleanup

Unmanaged resources are items which aren't in the control of the CLR and garbage collector. Items like file handles, memory returned from PInvoke, etc ... If these resources aren't explicitly freed by user code they will leak and be around for the remainder of the process lifetime. It's critical that they are freed.

This is where the finalizer comes in. It will run on an object just before it is collected by the CLR. This doesn't require the consumer follow the disposable pattern and hence is a good fallback for ensuring unmanaged resources are freed to prevent a leak.

If your code doesn't contain any directly held unmanaged resources then there is no reason to have a finalizer. It is the responsibility of the code which holds the unmanaged resource to have the finalizer.



来源:https://stackoverflow.com/questions/10854801/why-do-i-need-a-finalizer-if-my-class-implements-idisposable

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!