When are asp.net controls disposed
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);
}
开发者_StackOverflow 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);
}
}
When are asp.net controls disposed
Never, if there is any live reference.
Calling the Dispose
method is best practice if you have any Disposable
Objects. 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 the Dispose
method and SuppressFinalization
.
And the other thing is in your code example. Having a Finalize
method 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 if disposing
. So, there is no point of adding Finalize
method if you don't have any unmanaged objects.
The object will be added to the Finalization Queue and call the Finalize
method 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. Otherwise Finalize
will 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#
the only time you need to touch it is when you want it to be cleaned NOW
Or if you are going to enter a block which creates a lot of objects.
Otherwise - let the GC decide.
p.s. why don't you use the USING mechanism ?
Your objects would only be cleaned up once the garbage collector decides that it is ready to run. Generally, you would only implement a dispose if you needed to clean up non-managed resources (like filehandles etc) or external connections. If you are seeing these resources for a long time and through multiple collections then something is probably holding on to a reference somewhere.
The use of dispose is not wrong from what I see ... its not really getting you anything. You are dropping the reference to the event but the underlying objects are going to remain on the heap until the GC decides to collect them.
精彩评论