I’m hunting memory leaks in an asp.net website. One that I found was that the code wasn’t releasing event handlers when controls were no longer needed. I went with the disposing pattern as shown on MSDN to clean them up, and put the calls to remove the event handlers inside the if (disposing) block since they were managed resources, but unless I go through and add destructors to each page and have them all manually dispose the controls nothing fires until the finalizer cleans up the mess. Doing it that way would be brittle and make re-introducing a leak in the future relatively easy; would I be better off ignoring the convention about not touching non-managed objects in code ran by the finalizer?
// Design pattern for a base class.
public class Base: IDisposable
{
//Implement IDisposable.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
myControl.SomeEvent -= SomeEventHandler;
// Free other state (managed objects).
}
// Free your own state (unmanaged objects).
// Set large fields to null.
}
// Use C# destructor syntax for finalization code.
~Base()
{
// Simply call Dispose(false).
Dispose (false);
}
}
Never, if there is any live reference.
Calling the
Disposemethod is best practice if you have anyDisposableObjects. If you just allow them to go out of scope, they will be added to the finalization queue in the first garbage collection cycle. And will release the memory in the second garbage collection cycle after finalization. Finalization is an unwanted overhead if you can call theDisposemethod andSuppressFinalization.And the other thing is in your code example. Having a
Finalizemethod without having any unmanaged code. If you look at the execution path of the Finalize->Dispose(false) you can notice that it does nothing. Because all the managed objects are handled only ifdisposing. So, there is no point of addingFinalizemethod if you don’t have any unmanaged objects.The object will be added to the Finalization Queue and call the
Finalizemethod only if that object doesn’t have any live references (in the first GC cylcle). So, it’s your duty to un-register necessary events. OtherwiseFinalizewill never execute as long as there is a reference to that object.Here is a good reference for you on un-registering event handlers.
Is it necessary to explicitly remove event handlers in C#