Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

standard dispose pattern? why do we need "disposing" parameter in the virtual method and isn't the finalizer get called after dispose always?

Tags:

c#

.net

c#-3.0

Why do we need parameter disposing in the below code snippet.

Moreover we invoke dispose with false, in finalizer and it won't release or do the clean up.

So what if dispose never get called?

Isn't dispose always get called before finalizer?

using System;
public class MyClass : IDisposable 
{ 
    private bool disposed = false;  
    protected virtual void Dispose(bool disposing) 
    {    
        if (!disposed)
        {
            **//Do we really need this condition?
            if (disposing)**
            { 
                // called via myClass.Dispose().    
                // OK to use any private object references
            }
            disposed = true; 
        } 
    }
    public void Dispose() 
        // Implement IDisposable     
    {
        Dispose(true);   
        GC.SuppressFinalize(this); 
    } 
    ~MyClass() // the finalizer
    {
        //why do we need to call with false?
        Dispose(false);    
    }
} 

In other words, why not?

using System;
public class MyClass : IDisposable 
{ 
    private bool disposed = false;  
    protected virtual void Dispose(bool suppressFinalize) 
    {    
        if (!disposed)
        {
            //Do we really need this condition?

                // called via myClass.Dispose().    
                // OK to use any private object references            
            disposed = true; 
        }
        if (!suppressFinalize)
        {
            GC.SuppressFinalize(this); 
        }
    }
    public void Dispose() 
        // Implement IDisposable     
    {
        Dispose(true);   

    } 
    ~MyClass() // the finalizer
    {
        //why do we need to call with false?
        Dispose(false);    
    }
} 

In fact, do I really need finalizer? Why not this?

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

} 
like image 499
Dreamer Avatar asked Jun 01 '12 17:06

Dreamer


People also ask

Why do we have the Dispose () method?

The dispose pattern is used for objects that implement the IDisposable interface, and is common when interacting with file and pipe handles, registry handles, wait handles, or pointers to blocks of unmanaged memory. This is because the garbage collector is unable to reclaim unmanaged objects.

What should be in Dispose method?

The Dispose Method—Explicit Resource Cleanup Unlike Finalize, developers should call Dispose explicitly to free unmanaged resources. In fact, you should call the Dispose method explicitly on any object that implements it to free any unmanaged resources for which the object may be holding references.

Is Dispose method called automatically?

Dispose() will not be called automatically. If there is a finalizer it will be called automatically. Implementing IDisposable provides a way for users of your class to release resources early, instead of waiting for the garbage collector.

When Dispose method is called?

. NET GC is non-deterministic (i.e. you never know nor should you depend on when it happens) Dispose is never called by the . NET Framework; you must call it manually - preferably by wrapping its creation in a using() block.


1 Answers

Moreover we invoke dispose with false, in finalizer and it wont release or do the clean up.

Indeed - it will assume that other classes handle their own cleanup in that case, and only do the clean-up of direct unmanaged resources.

So what if dispose never get called?

Then the finalizer will be called, and it will clean up any direct unmanaged resources, but not worry about indirect resources.

Isn't dispose always get called before finalizer?

Not if no-one calls it for whatever reason.

I think this pattern is more complicated than it needs to be, as it's trying to account for classes which act as base classes for other classes which might need finalizers. Seal your classes and you can just implement exactly what you'd expect to :)

You might also want to read Joe Duffy's "Never write a finalizer again" blog post and the long explanation of the pattern.

like image 134
Jon Skeet Avatar answered Nov 15 '22 14:11

Jon Skeet