Priyank Bolia
Priyank Bolia

Reputation: 14433

C# memory and dispose related questions

I have the following piece of code, just wanted to check who will call the dispose? is it called automatically.

ToolTip toolTip = new ToolTip();
toolTip.SetToolTip(button, toolTipText);

Also let say I create a Timer local variable, who will call the dispose, what about memory leaks, as, if I call the dispose right away, the timer event, won't be fired.

Do I need to make sure that in the timer event handler dispose is called, even if I don't have any reference to the timer variable. Also do I need to unregister the event handler for that timer.

Edit:

Upvotes: 0

Views: 1744

Answers (5)

ICR
ICR

Reputation: 14162

In .NET the garbage collector will automatically free memory when an object can no longer be referenced from anywhere. When it does so, if the object has a finalizer it calls the finalizer. The finalizer is for cleaning up, usually unmanaged resources.

However, finalizers are expensive (they delay garbage collection on an object, for example) and you cannot tell when it will be run (as you can't tell when the GC will decide to collect it). They are usually left as a last resort for cleaning up things like unmanaged resources.

This is where the IDisposable interface and it's Dispose method comes in. Dispose can also be used to clean up, both managed and unmanaged resources. When you call the Dispose method it cleans up and the object is no longer in a stable, usable state.

If you have a resource which implements IDisposable you can call Dispose on it when you know you are done. That way and resources it is holding on to can be freed up as soon as possible. The usual way of doing this is to wrap it up in a using statement, which will automatically Dispose when the using block is done. e.g.:

using (SomeDisposableObject disposableObject = new SomeDisposableObject())
{
     disposableObject.DoSomeStuff();
     disposableObject.DoSomeMoreStuff();
}

When the using block is finished (after DoMoreStuff) Dispose is called on disposableObject. Using statements are a lot cleaner than the equivalent code when you take into account exception handling.

In the case of something like ToolTip, which has unmanaged references (a lot of WinForms in a wrapper around the unmanaged Win32 components) it will have a finalizer to make doubly sure the unamanged resources are freed correctly. However, if you call Dispose on the object, the cleanup code is run there and then and the finalizer is suppressed (it won't run when the object is collection by the GC).

So, to answer your question more directly, if you know exactly when an IDisposable is finished with it is a good idea to call Dispose. However, if you don't it is usually ok just to leave it up to the garbage collector to collect it and call the relevant code to correctly cleanup the object.

In the cases of ToolTip and Timer given, I wouldn't worry about calling Dispose on them yourself as I suspect it would be difficult to predict when they will be finished with.

Upvotes: 1

Hans Passant
Hans Passant

Reputation: 941317

ToolTip registers event handlers on the control on which it is shown. It's Hide() method is automatically called when the form's Deactivate event fires. Which will happen when the form is closed. That in turn ensures that its Windows handle is destroyed and event handlers are unregistered. After that there are no disposable objects left.

You can verify this for yourself with Reflector or the Reference Source. Relevant methods are, in order, BaseFormDeactivate, HideAllToolTips, Hide, ClearTopLevelControlEvents.

You don't have to call Dispose(), you don't have a leak.

Upvotes: 7

Samuel Neff
Samuel Neff

Reputation: 74899

You need to call Dispose on anything that implements IDisposable, or at least make sure something does. For UI components, add them to a form's Controls collection and they'll get disposed when the form closes. For other things you need to keep a reference to them and call dispose appropriately. It may be appropriate to make your class implement IDisposable just to call Dispose on your composed objects.

Upvotes: 1

Guvante
Guvante

Reputation: 19203

Dispose is a method provided to allow you to release the object immediately. For example an exclusive file stream.

Finalize is a method that automatically releases any resources the object is using once it is no longer being used by your program.

You only need to worry about disposing when the object uses exclusive or finite resources. Examples being the file one, or a database connection. (Note that in both these cases Close is equivalent to disposing)

To answer your question, you are not disposing at all, but letting the finalizer run when it needs to.

Upvotes: 2

thecoop
thecoop

Reputation: 46098

Generally, it's up to the object registering to an event to un-register - not doing so will create memory leaks. You should not rely on a Dispose method doing so.

Dispose is not called automatically, unless you wrap the object in a using() {} statement, or add it to the objects IContainer instance (if it's a designer class). If it's a class variable, you need to make the containing class implement IDisposable and dispose of the instance in it.

Upvotes: 0

Related Questions