Reputation: 1544
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
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
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
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
Reputation: 155
You can use AOP in this case. Aspect-Oriented Programming Enables Better Code Encapsulation and Reuse
Upvotes: 0