Andrei Sedoi
Andrei Sedoi

Reputation: 1544

Object Garbage Collection Event in .NET

Is there any way to execute some code before some concrete class instance is garbage collected? If yes, what is it?

Upvotes: 0

Views: 130

Answers (4)

Tomasz Jaskuλa
Tomasz Jaskuλa

Reputation: 16013

You might also be interested in reading great article by Shawn Farkas Digging into IDisposable http://msdn.microsoft.com/en-us/magazine/cc163392.aspx

Upvotes: 0

Eamon Nerbonne
Eamon Nerbonne

Reputation: 48066

This is the IDisposable pattern. If you wish to dynamically alter the code run by Dispose, use a delegate, e.g.

sealed class DelegatedDisposable : IDisposable {
    readonly Action disposer;
    void IDisposable.Dispose() { disposer(); }
    public DelegatedDisposable(Action onDispose) { disposer = onDispose; }
}

A simple wrapper might suffice for you, in which you store the object to be disposed:

sealed class WrappedDisposable<T> : IDisposable where T : IDisposable {
    readonly Action<T> onDispose;
    readonly T wrappedDisposable;
    public WrappedDisposable(T disposable, Action<T> callOnDispose) {
        if(disposable == null) throw new ArgumentNullException("disposable");
        if(callOnDispose == null) throw new ArgumentNullException("callOnDispose");
        wrappedDisposable = disposable;
        onDispose= callOnDispose;
    }
    void IDisposable.Dispose() { 
        try{ onDispose(wrappedDisposable); } 
        finally { wrappedDisposable.Dispose(); }
    }
}

If you wish to execute code before an object is garbage collected, you need to implement a finalizer, which in C# looks like a private constructor with a ~ before its name. You generally don't need to do this unless you're manually managing native resources (i.e. caused a native malloc lock allocation or whatnot).

Upvotes: 1

Ash
Ash

Reputation: 2601

it depends on what you want to do before the dispose. There are many things like long running ops , ops that can throw exception etc that are not recommended.Do you want to trigger some execution OnDispose..

You can somehow do it by doing the below but again I am not sure what you want to do so I will not recommend it .

I normally have IDisposible where I am using unmanaged resources and instantiate the class in using() and do my ops there. After the scope of using the Dispose will be called so in the using block I cna execute my code. //have a destructor

~ MyClass() 
{
    //Do something here.
   // Cleaning up code goes here
}

This is translated to

protected override void Finalize()
{
   try
   {
      // Do something here. Dont throw exception here.
      // Cleaning up .
   }
   finally
   {
      base.Finalize();
   }
}

If you class implemets IDisposible you can have the extra bit of code in you Dipose

protected virtual void Dispose(bool disposing)
    {
        //Do something before resource free up.
        if (disposing) 
        {
            // free managed resources
            if (managedResource != null)
            {
                managedResource.Dispose();
                managedResource = null;
            }
        }
        // free native resources if there are any.
        if (nativeResource != IntPtr.Zero) 
        {
            Marshal.FreeHGlobal(nativeResource);
            nativeResource = IntPtr.Zero;
        }
    }

Upvotes: 0

Gaurav Saxena
Gaurav Saxena

Reputation: 155

You can use AOP in this case. Aspect-Oriented Programming Enables Better Code Encapsulation and Reuse

Upvotes: 0

Related Questions