Does it make sense in FormClosed to do Me.Dispose

C

Cor Ligthert [MVP]

I can call thousands but just one

Label?

Cor

Michael C said:
Still, Dispose should be called on forms. In this case it is not necessary
because Dispose is called for you. It is a bit of a special situation
because in most cases it is not. Can you name any class in dot net that
has dispose where it makes no sense at all to have it? Something might
exist but it will be rare.


The MS documentation specifies that IDispose indicates a resourse that
needs disposing asap. The ToString documention doesn't specify any such
requirement.

Michael
 
R

rowe_newsgroups

Label?

Do you have the inner implementation details of a Label? How can you
call something a waste of time if you can't be sure that it does
absolutely nothing?

Anyways, at the very least wouldn't calling dispose at least prevent
the Label from having to go through two cycles of garbage collection?
(as it probably uses GC.SuppressFinalize)

Besides if it wasn't needed, why would the parent call it's dispose
method from it's own dispose method?

Lastly, let me adapt Michael's question a little:

Can you show us some examples where manually calling Dispose is
detrimental to the application?

Thanks,

Seth Rowe
 
C

Chris Dunaway

My belief was you needed to dispose all forms after they were closed. You
say only if it's shown using ShowDialog. But I've just tested and my tests
indicate we are both wrong. For a form shown via either method the window
handle for the form gets destroyed immediately it is closed. I tested using
the close button on the title bar, using a cancel button and just calling
Me.Close. In all cases the window itself was destroyed immediately. I
checked this by overriding WndProc and looking for WM_DESTROY and confirmed
it using spy++. I could not get the window itself to remain after the form
was closed.

I'm not sure that the fact that the window handle gets destroyed is
proof that the form object has been disposed.
From the docs:

"When a form is closed, all resources created within the object are
closed and the form is disposed. The two conditions when a form is not
disposed on Close is when (1) it is part of a multiple-document
interface (MDI) application, and the form is not visible; and (2) you
have displayed the form using ShowDialog. In these cases, you will
need to call Dispose manually to mark all of the form's controls for
garbage collection."

Further, if you try these two snippets of code:

Dim frm As New Form2
frm.ShowDialog()
System.Threading.Thread.Sleep(3000)
frm.ShowDialog()
frm.Dispose()

Dim frm2 As New Form2
frm2.Show()
System.Threading.Thread.Sleep(3000)
frm.Show()

The first will work correctly, even after closing the form. The
second will throw an exception.

One reason for not disposing a form when shown using ShowDialog is
that you may wish to access the form's properties after it has been
closed. The Open File Dialog is a good example of this.

But if you try to access a form that was displayed with Show() after
it has been closed, you will get an exception.

Chris
 
A

active

Michael C said:
My belief was you needed to dispose all forms after they were closed. You
say only if it's shown using ShowDialog. But I've just tested and my tests
indicate we are both wrong. For a form shown via either method the window
handle for the form gets destroyed immediately it is closed. I tested
using the close button on the title bar, using a cancel button and just
calling Me.Close. In all cases the window itself was destroyed
immediately. I checked this by overriding WndProc and looking for
WM_DESTROY and confirmed it using spy++. I could not get the window itself
to remain after the form was closed.

Michael
I'm not sure if this is relevant, but you can continue to access (I think)
the (ShowDialog) window's properties after it is closed. Doesn't that mean
it is not disposed?
 
R

rowe_newsgroups

I'm not sure that the fact that the window handle gets destroyed is
proof that the form object has been disposed.

You are absolutely right - the destruction of the window handle has
nothing to do with the disposing of the form.

Here's a quick demo:

Create a new windows app and drop 3 buttons onto the form, then add
this code to the form:

Public Class Form1

<System.Runtime.InteropServices.DllImport("user32.dll")> _
Public Shared Function DestroyWindow(ByVal hWnd As IntPtr) As
Boolean

End Function

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles Button1.Click
DestroyWindow(Me.Handle)
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles Button2.Click
Dim f As New Form1()
f.Text = "Created With Show"
f.Show()
End Sub

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles Button3.Click
Dim f2 As New Form1()
f2.Text = "Created With ShowDialog"
f2.ShowDialog()
End Sub

'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
MsgBox(String.Format("Form {0} is disposing", Me.Text))
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub

End Class

Press Button2 or Button3 to create and Show/ShowDialog a new Form1
form. Then on the newly created form press it's Button1 to invoke the
DestroyWindow api call on the form. *Poof* goes the form, but no
Dispose messagebox will be shown. Only when the startup form closes
(and the application exits) will the Dispose be called on these forms
and the messages show up.

Thanks,

Seth Rowe
 
C

Cor Ligthert [MVP]

No do you?

Cor

rowe_newsgroups said:
Do you have the inner implementation details of a Label? How can you
call something a waste of time if you can't be sure that it does
absolutely nothing?

Anyways, at the very least wouldn't calling dispose at least prevent
the Label from having to go through two cycles of garbage collection?
(as it probably uses GC.SuppressFinalize)

Besides if it wasn't needed, why would the parent call it's dispose
method from it's own dispose method?

Lastly, let me adapt Michael's question a little:

Can you show us some examples where manually calling Dispose is
detrimental to the application?

Thanks,

Seth Rowe
 
C

Cor Ligthert [MVP]

Yes,

And to make this ever more relevant, why did they make the method IsDisposed
for.

Although we are here again seeing people who are completely mixing up
Finalizing with Disposing.

Cor
 
R

rowe_newsgroups

No do you?

It's difficult to know what you're replying to as you didn't quite me
before your response, but I'm guessing you're asking if I know the
inner implementation details of a Label's dispose method. And the
answer is of course not. With that said I can think of three things
that could be happening inside the Dispose method:

1) It does nothing
2) It does something beneficial
3) It does something detrimental

In case 1 calling Dispose would at least prevent it from going through
2 cycles of garbage collection. So why not call Dispose here?

In case 2 calling Dispose would help out the program. So why not call
Dispose here?

In case 3 calling Dispose would hurt the program's performance, but we
know that eventually the GC will call it's finallizer, which will most
likely call it's Dispose method, which will still give us the same
performance hit at a later time. At least we can control when the
detrimental effects happen versus waiting for the GC to run (which
happens when it needs to - which is normally when the application is
doing heavy processing - so the further hit from Disposing of the
Label then would further decrease performance). So why not call
Dispose here?

Have I convinced you yet that calling Dispose on a Label is not
pointless?

Thanks,

Seth Rowe
 
C

Cor Ligthert [MVP]

Seth,

In what time is the garbage collector working?

Exactly in idle time. And that is very often therefore it is so nice that
that is proven in this thread with a sample that forms mostly very quick
gone after closing.

But how can somebody find benifictal things in processes that is working in
the time as the processor is maybe very needed for very important processes.
Sorry, I don't understand that.

Cor
 
A

active

Can someone explain this test result?

It shows the open dialog twice.

After the Dispose I wouldn't expect the box was still useful

Unless the Dispose does nothing

If so why have it?

Anyone know what is going on here?



GC.Collect()

OpenFileDialog1.ShowDialog()

OpenFileDialog1.Dispose()

GC.Collect()

OpenFileDialog1.ShowDialog()
 
H

Herfried K. Wagner [MVP]

rowe_newsgroups said:
It's difficult to know what you're replying to as you didn't quite me
before your response, but I'm guessing you're asking if I know the
inner implementation details of a Label's dispose method. And the
answer is of course not. With that said I can think of three things
that could be happening inside the Dispose method:

1) It does nothing
2) It does something beneficial
3) It does something detrimental

In case 1 calling Dispose would at least prevent it from going through
2 cycles of garbage collection. So why not call Dispose here?

In case 2 calling Dispose would help out the program. So why not call
Dispose here?

In case 3 calling Dispose would hurt the program's performance, but we
know that eventually the GC will call it's finallizer, which will most
likely call it's Dispose method, which will still give us the same
performance hit at a later time.

I fully agree. Especially if 'Dispose' does nothing, then calling it
doesn't hurt the program's performance much.

The rule I am following is that calling 'Dispose' too often causes less
problems than not calling it at all.
At least we can control when the
detrimental effects happen versus waiting for the GC to run (which
happens when it needs to - which is normally when the application is
doing heavy processing - so the further hit from Disposing of the
Label then would further decrease performance). So why not call
Dispose here?

Have I convinced you yet that calling Dispose on a Label is not
pointless?

It depends on the specific situation. In general you need to call 'Dispose'
only on objects you created. In addition, adding a control to a form will
cause it to be disposed automatically if the parent form gets disposed. So
it is not necessary to remove all the controls from the form and call their
'Dispose' method.
 
H

Herfried K. Wagner [MVP]

Cor,

Cor Ligthert said:
In what time is the garbage collector working?

Exactly in idle time. And that is very often therefore it is so nice that
that is proven in this thread with a sample that forms mostly very quick
gone after closing.

Will this help if your system hangs because your applications holds lots of
GDI handles, for example, and the GC does not know that they can be freed
because the objects holding them have to wait some collection generations
for their disposal and finalization?

The main problem is not performance, it's that the CLR/GC does not know
anything about unmanaged resources. That's why the GC is useless when
dealing with unmanaged resources and why we have to provide functionality to
release unmanaged resources in time. The GC knows nothing about the
semantics of a class, but this knowledge is required to release the
unmanaged resources which are not needed any more by your application.
But how can somebody find benifictal things in processes that is working
in the time as the processor is maybe very needed for very important
processes. Sorry, I don't understand that.

As I said, I believe that the performance argument doesn't count nowadays as
it did some years ago. Calling 'Dispose' is a "constant factor" that can be
ignored. Choosing ideal data structures etc. will help much more to make an
application faster. If performance would still count, we would not use the
blown up .NET Framework's classes to write Windows applications, for
example.
 
M

Michael C

Cor Ligthert said:
I can call thousands but just one

Label?

Label uses a window handle so is most definately a finite resource that
needs to be disposed. In fact it is a very good example of why dispose is
implemented because a form could potentially have a large number of labels
using up a large number of windows handles. So please try again. :)

Michael
 
M

Michael C

Cor Ligthert said:
No do you?

I don't know all the details but I know some. When you create a label object
it creates a window handle. When you call dispose it destroys the window
handle. But that is not relevant. The point of implementing IDiposable is
that I don't need to know the implementation, just that Dispose should be
called asap.

Michael
 
H

Herfried K. Wagner [MVP]

rowe_newsgroups said:
Do you have the inner implementation details of a Label? How can you
call something a waste of time if you can't be sure that it does
absolutely nothing?

I agee. Speaking more generally, interfaces are contracts. If a class (or
one of its derived classes, which one does not matter) implements
'IDisposable', this means "I cannot guarantee that I will never need
unmanaged resources". Even if the current implementation does not use
unmanaged resources, by implementing the interface it indicates that this is
not guaranteed. Imagine even the case that another implementation of the
class than those contained in the .NET Framework may actually use unmanaged
resources and thus calling 'Dispose' makes perfect sense.

Unfortunately developers even nowadays spend a lot of time on
micro-optimizations which are often "unclean" hacks which will work on their
system, using a certain implementation, ..., but which are
counter-productive from the long-term perspective.
Besides if it wasn't needed, why would the parent call it's dispose
method from it's own dispose method?

Lastly, let me adapt Michael's question a little:

Can you show us some examples where manually calling Dispose is
detrimental to the application?

I don't think such an example exists (if the call is performed if the object
is not in use any more) because a method call is done quickly and its better
to do it sooner than later in order to prevent a resource bottleneck.
 
C

Cor Ligthert [MVP]

Michael,

In my opinion are you all the time talking about finalizing and calls it
dispose.

There is no name shift in Net. Dispose is something else than finalizing.

Dispose is to give unmanaged resources to the GC.

Cor
 
C

Cor Ligthert [MVP]

Herfried,
I agee. Speaking more generally, interfaces are contracts. If a class
(or one of its derived classes, which one does not matter) implements
'IDisposable', this means "I cannot guarantee that I will never need
unmanaged resources". Even if the current implementation does not use
unmanaged resources, by implementing the interface it indicates that this
is not guaranteed.

But implementing IDisposable means direct that there is no need to call
dispose for all child members.
While we see that the sample implementation shows forever component in the
implementation.

However this combinantion gives direct the method dispose to every child and
a kind of foolish talking from people not knowing what to do on Internet
became populair.

"If you don't know why something is, than use it. I probably does not hurt"

Somebody who tells or write this in programming shows for me that he is an
absolute amateur.

Cor












Imagine even the case that another implementation of the
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top