By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,805 Members | 1,652 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,805 IT Pros & Developers. It's quick & easy.

Dispose(bool), Idisposable, form closing etc.

P: n/a
Hello,

I am confused by dispose etc. and hope someone can set me right.

1. The Dispose(Bool) the IDE generates for a form has nothing to do
with IDisposable, right?
2. So when is this called? When a form is closed? If this is caused
automatically when a form is closed how can I then access things on a
modal from after ShowDialog() returns? Or is it only for modeless
forms?
3. Does the garbage collector automically call Dispose() which is part
of IDisposable when an onbject is garbage collected? I know this is
non-deterministic etc. Is this what is known as the Finalizer or
whatever it's called?
4. I don't understand how garbage collection works with forms. If I
have a method which declares a variable which is a form, and
instantiate it in the same routine, when I leave the routine the
variable is released, the form's reference count should then be zero
and therefore a candiate for garbage collection, no? Is there another
refernce to it somewhere?

Confused,

Ray

Nov 19 '07 #1
Share this Question
Share on Google+
19 Replies


P: n/a
On 2007-11-19 12:14:30 -0800, rbrowning1958 <RB***********@gmail.comsaid:
Hello,

I am confused by dispose etc. and hope someone can set me right.

1. The Dispose(Bool) the IDE generates for a form has nothing to do
with IDisposable, right?
I wouldn't go that far. It's not part of the interface, but it is part
of the common implementation of the interface.
2. So when is this called? When a form is closed? If this is caused
automatically when a form is closed how can I then access things on a
modal from after ShowDialog() returns? Or is it only for modeless
forms?
Forms shown with ShowDialog() are not disposed when they are closed.
3. Does the garbage collector automically call Dispose() which is part
of IDisposable when an onbject is garbage collected? I know this is
non-deterministic etc. Is this what is known as the Finalizer or
whatever it's called?
If you have not called Dispose(), then the finalizer won't be
suppressed and the finalizer may eventually be called. The object
cannot be collected until the finalizer is run (for objects that have a
finalizer and don't suppress finalizing).
4. I don't understand how garbage collection works with forms.
It works the same as for other classes that implement IDisposable.
If I
have a method which declares a variable which is a form, and
instantiate it in the same routine, when I leave the routine the
variable is released, the form's reference count should then be zero
and therefore a candiate for garbage collection, no? Is there another
refernce to it somewhere?
There's no referencing counting.

As far as eligibility for garbage collection goes, what matters is
where there's a reference to the form somewhere else. In the case of a
form, its instance is added to the application's list of open forms,
which you can retrieve from the Application.OpenForms property.

So, yes...there's still a reference to the form somewhere.

Pete

Nov 19 '07 #2

P: n/a
On Nov 19, 2:14 pm, rbrowning1958 <RBrowning1...@gmail.comwrote:
Hello,

I am confused by dispose etc. and hope someone can set me right.

1. The Dispose(Bool) the IDE generates for a form has nothing to do
with IDisposable, right?
Well, it is related because that is required for the canonical
implemenation of IDisposable. But, you are correct. There is no
strict relationship between Dispose(bool) and IDisposable.
2. So when is this called? When a form is closed? If this is caused
automatically when a form is closed how can I then access things on a
modal from after ShowDialog() returns? Or is it only for modeless
forms?
It is called when either the IDisposable.Dispose method is called from
user code or as a last resort by the GC when Finalize is called. It's
been awhile, but I don't think closing a modal form disposes it.
Furtheremore, some (most?) class authors choose to allow property
getters to return even after the object has been disposed.
3. Does the garbage collector automically call Dispose() which is part
of IDisposable when an onbject is garbage collected? I know this is
non-deterministic etc. Is this what is known as the Finalizer or
whatever it's called?
The GC will not call IDisposable.Dispose. However, it may indirectly
call Dispose(bool) because it's part of the Finalize method
(destructor in C#)...at least if you've choosen the canonical
implementation of IDisposable.
4. I don't understand how garbage collection works with forms. If I
have a method which declares a variable which is a form, and
instantiate it in the same routine, when I leave the routine the
variable is released, the form's reference count should then be zero
and therefore a candiate for garbage collection, no? Is there another
refernce to it somewhere?
No, there is no reference counting involved. Assuming the form
doesn't somehow register itself in a static data structure then it
should be a candidate for garbage collection once it falls out of
scope.
>
Confused,

Ray
Nov 19 '07 #3

P: n/a
Ray,

See inline:
Thank you all for replying I've arbitrarily chosen yours to reply to,
Nicholas.
I'm flattered =P
So let me see if I have this right:

1. Dispose(Bool) as part of a form is not explicitly part of the
IDisposable interface, but the implementation of IDisposable,Dispose
further up the class hierarchy (form I suppose) calls this. This is
waht Brian called the Canonical implementation (I never did understand
what that word meant!).
Yep.
2, When a modeless form is called, clicking the form's close button,
or calling the close() method calls IDisposable.Dispose which in turn
calls Dispose(bool).
Yep.
3. If it's a modal form, clicking the close button or calling the
close method just hides the form, and does not call
IDisposable.dispose. Therefore I have to do it myself or use a Using
clause.
Yep.
4. A form's destructor will call Dispose(bool) although in most cases
it will not do much because it will already have been called by
IDisposable.dispose. SO...I'm guessing that Idisposable calls
dispose(true), whereas the destructor calls Dispose(false)?
Yep.
5. With regard to garbage collecting - doesn't Peter have it correct
where he says the form is not garbage collected because it is
referenced by application.openForms?
Yep.
6. Brian mentioned that some class authors write property getters to
return data even after the form has been destroyed - I don't
understand this. Doesn't this mean the property getter has to be
static - and where would it savbe the data? In static class vars? That
implies I only have one instance of the form, right?
No. The properties would be instance, and you would access them off the
form instance before you call Dispose on the form. You ^could^ get away
with accessing the properties after dispose is called, but only if they are
fields that store data that is not dependent on accessing the disposed form
itself.

For example, if you had a text box with text in it, and then you showed
the form modally, if you expose the text in the textbox in a property by
calling the Text property on the textbox, you will get an exception if you
try to access that property after the form is disposed (since the textbox is
disposed of as well). However, if you store the contents of the TextBox in
a string before you dispose of the form, and then access the string in the
property, you won't have a problem, even if the form is disposed.

However, I don't think you should worry about transferring all of your
control values to fields (instead of accessing the values on the controls
from the properties/methods), as it's completely reasonable to expect that
your object won't work once disposed.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
>
Thanks everbody,

Best

Ray

Nov 20 '07 #4

P: n/a
"rbrowning1958" <RB***********@gmail.comschrieb im Newsbeitrag
news:db**********************************@41g2000h sh.googlegroups.com...
>
6. Brian mentioned that some class authors write property getters to
return data even after the form has been destroyed - I don't
understand this. Doesn't this mean the property getter has to be
static - and where would it savbe the data? In static class vars? That
implies I only have one instance of the form, right?
Dispose does not delete the instance. It only frees, what should not wait
for the GC to be freed. The fields of the instance still live on, until the
instance is collected. So any propertie, that does not depend on the 'open
state' of the form will be accessible. This includes all properties that
simply access fields. But, in case of a form, you can't access f.e. the
controls of the form (or at least, you shouldn't count on).
If the form is destroyed in the sense, that it is collected, than there is
no reference to the instance left (if the GC worked right ;-) ), and so no
member of the instance can be accessed.

Christof

Nov 20 '07 #5

P: n/a
"rbrowning1958" <RB***********@gmail.comwrote in message
news:db**********************************@41g2000h sh.googlegroups.com...
5. With regard to garbage collecting - doesn't Peter have it correct
where he says the form is not garbage collected because it is
referenced by application.openForms?
I'm just guessing here but I'd imagine that application.openForms keeps what
is called a weak reference to the form. This means that if all other
references are dropped then the GC can kill the references in openForms.
6. Brian mentioned that some class authors write property getters to
return data even after the form has been destroyed - I don't
understand this. Doesn't this mean the property getter has to be
static - and where would it savbe the data? In static class vars? That
implies I only have one instance of the form, right?
No, they are instance members. Remember the form is only hidden so
everything can be accessed still

Michael
Nov 20 '07 #6

P: n/a
On 2007-11-20 15:50:15 -0800, "Michael C" <mi**@nospam.comsaid:
"rbrowning1958" <RB***********@gmail.comwrote in message
news:db**********************************@41g2000h sh.googlegroups.com...
>5. With regard to garbage collecting - doesn't Peter have it correct
where he says the form is not garbage collected because it is
referenced by application.openForms?

I'm just guessing here but I'd imagine that application.openForms keeps what
is called a weak reference to the form. This means that if all other
references are dropped then the GC can kill the references in openForms.
No, that's not true. If it were, forms applications would be in a
world of hurt. After all, they by default all start out like this:

void Main()
{
...
Application.Run(new Form1());
}

At a minimum, in the Run() method, there'd have to be some strong
reference to the parameter passed in. But more significantly, this
sort of code:

void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();

form2.Show();
}

which is quite common, would never work if what you say is true.

No, I believe that the list that is exposed as Application.OpenForms is
a list of plain old strong references. The application code itself is
not required to maintain a reference, so there must be a strong
reference somewhere else and the underlying list implementing OpenForms
is the most likely source.

Now that VS2008 is out, it's only a matter of time before you can go
look yourself if you don't believe me. :) In the meantime, you could
get Reflector and look at the implementation. I've never tried it
myself, but I'm confident at what I might find should I try. Weak
references just wouldn't do the job.

Pete

Nov 21 '07 #7

P: n/a
On Nov 20, 5:21 am, rbrowning1958 <RBrowning1...@gmail.comwrote:
1. Dispose(Bool) as part of a form is not explicitly part of the
IDisposable interface, but the implementation of IDisposable,Dispose
further up the class hierarchy (form I suppose) calls this. This is
waht Brian called the Canonical implementation (I never did understand
what that word meant!).
I used the word canonical to mean an authorized, well-established
pattern.
2, When a modeless form is called, clicking the form's close button,
or calling the close() method calls IDisposable.Dispose which in turn
calls Dispose(bool).

3. If it's a modal form, clicking the close button or calling the
close method just hides the form, and does not call
IDisposable.dispose. Therefore I have to do it myself or use a Using
clause.

4. A form's destructor will call Dispose(bool) although in most cases
it will not do much because it will already have been called by
IDisposable.dispose. SO...I'm guessing that Idisposable calls
dispose(true), whereas the destructor calls Dispose(false)?

5. With regard to garbage collecting - doesn't Peter have it correct
where he says the form is not garbage collected because it is
referenced by application.openForms?

6. Brian mentioned that some class authors write property getters to
return data even after the form has been destroyed - I don't
understand this. Doesn't this mean the property getter has to be
static - and where would it savbe the data? In static class vars? That
implies I only have one instance of the form, right?
I don't think I was very clear. What I meant was that you may still
be able to call some property getters without them throwing exceptions
even after Dispose has been called on the object. That's because
property getters are usually nothing more than trivial wrappers around
instance variables.
Nov 21 '07 #8

P: n/a
"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
news:2007112017431716807-NpOeStPeAdM@NnOwSlPiAnMkcom...
No, that's not true. If it were, forms applications would be in a world
of hurt. After all, they by default all start out like this:

void Main()
{
...
Application.Run(new Form1());
}
That wouldn't be a problem because application.Run would keep a reference.
Although you're probably right about everything else. I guess the form must
remove itself from the collection at some point.

Michael
Nov 21 '07 #9

P: n/a
On 2007-11-20 20:06:22 -0800, Peter Duniho <Np*********@NnOwSlPiAnMk.comsaid:
[...]
>Although you're probably right about everything else. I guess the form must
remove itself from the collection at some point.

I'm sure that when the form is actually disposed, it removes itself
from the open forms list.

Assuming this is true, it's also a highlight as to why it's so
important to dispose forms shown modally when you're done with them.
For many managed types that implement IDisposable, if you forget to
dispose them eventually it's likely that the finalizer will catch up
and go ahead and do that work for you.

But if a form isn't removed from the open forms list until it's
disposed, and a form isn't eligible for garbage collection until it's
removed from the open forms list, then a modal form that you don't
dispose will _never_ be garbage collected. It's a very serious
resource leak, much more so than the usual "didn't dispose" kind of bug.

Though, I admit I don't really know the details. Now I'm curious, so
if I get a moment I'll actually test it and see if I can figure out
what's going on.
So, I went ahead and checked this. Turns out, even a modal form is
removed from the open forms list when it's closed, even if not disposed.

So there's no really scary anti-finalizer bug you can create in your
application with Form.ShowDialog(). Which is not to say that you
should ignore the requirement to dispose a modal form when you're done
with it. Just that it's likely to eventually get disposed via the
usual finalizer "back-up" procedure even if you don't dispose it.

Pete

Nov 21 '07 #10

P: n/a
"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
news:2007112020512427544-NpOeStPeAdM@NnOwSlPiAnMkcom...
That doesn't tell you anything. As long as the reference is in the open
forms list (and of course it would be), the fact that the reference
remains valid until the function exits is meaningless.
No, I gave it a test with a regular class. The class would not be collected
until the function exited.
>
In fact, it's a given that the reference to the form would remain valid
until Application.Run() returns, because if that weren't true a forms
application would never work. By definition, the method returns when the
form is closed, so obviously the duration of the call to Application.Run()
and the lifetime of the form are _very_ closely tied to each other.
I wasn't talking about Application.Run at all. I was just using a regular
function that I defined myself and passed in an instance of a class I
defined. The only way I could get the class to be GCd before the function
exits was to set the parameter to null inside the function.
In other words, whatever test you did, all it accomplished was proving
that Application.Run() does in fact work. Which hopefully we all believed
already.
Rubbish.
There's no reason to believe that the collection of forms didn't exist
before. Just because it wasn't exposed to the application itself, that
doesn't mean it wasn't there.
That's true although that doesn't mean it did exist either.

Michael
Nov 21 '07 #11

P: n/a
"Michael C" <mi**@nospam.comschrieb im Newsbeitrag
news:uS**************@TK2MSFTNGP04.phx.gbl...
>
I wasn't talking about Application.Run at all. I was just using a regular
function that I defined myself and passed in an instance of a class I
defined. The only way I could get the class to be GCd before the function
exits was to set the parameter to null inside the function.
How did you test, that the instance was not GC'd?

Was it a debug version? Then the lifetime of the variable wasn't optimized
and extended the whole function, though it may not in an optimized build.

Christof

Nov 21 '07 #12

P: n/a
On 20 Nov, 16:13, "Christof Nordiek" <c...@nospam.dewrote:
"rbrowning1958" <RBrowning1...@gmail.comschrieb im Newsbeitragnews:db******************************** **@41g2000hsh.googlegroups.com...
6. Brian mentioned that some class authors write property getters to
return data even after the form has been destroyed - I don't
understand this. Doesn't this mean the property getter has to be
static - and where would it savbe the data? In static class vars? That
implies I only have one instance of the form, right?

Dispose does not delete the instance. It only frees, what should not wait
for the GC to be freed. The fields of the instance still live on, until the
instance is collected. So any propertie, that does not depend on the 'open
state' of the form will be accessible. This includes all properties that
simply access fields. But, in case of a form, you can't access f.e. the
controls of the form (or at least, you shouldn't count on).
If the form is destroyed in the sense, that it is collected, than there is
no reference to the instance left (if the GC worked right ;-) ), and so no
member of the instance can be accessed.

Christof
Hi Cristof,

What confused me - and is clear now - is that Dispose(bool) will
destroy the components / controls, but as someone else wrote if you
have their important properties stored in simple instance variables
then you can still access those until the form is destroyed (i.e. the
garbage collector has kicked in and freed the object's memory).

Cheers

Ray
Nov 26 '07 #13

P: n/a
On 21 Nov, 03:18, Brian Gideon <briangid...@yahoo.comwrote:
On Nov 20, 5:21 am,rbrowning1958<RBrowning1...@gmail.comwrote:
1. Dispose(Bool) as part of a form is not explicitly part of the
IDisposable interface, but the implementation of IDisposable,Dispose
further up the class hierarchy (form I suppose) calls this. This is
waht Brian called the Canonical implementation (I never did understand
what that word meant!).

I used the word canonical to mean an authorized, well-established
pattern.


2, When a modeless form is called, clicking the form's close button,
or calling the close() method calls IDisposable.Dispose which in turn
calls Dispose(bool).
3. If it's a modal form, clicking the close button or calling the
close method just hides the form, and does not call
IDisposable.dispose. Therefore I have to do it myself or use a Using
clause.
4. A form's destructor will call Dispose(bool) although in most cases
it will not do much because it will already have been called by
IDisposable.dispose. SO...I'm guessing that Idisposable calls
dispose(true), whereas the destructor calls Dispose(false)?
5. With regard to garbage collecting - doesn't Peter have it correct
where he says the form is not garbage collected because it is
referenced by application.openForms?
6. Brian mentioned that some class authors write property getters to
return data even after the form has been destroyed - I don't
understand this. Doesn't this mean the property getter has to be
static - and where would it savbe the data? In static class vars? That
implies I only have one instance of the form, right?

I don't think I was very clear. What I meant was that you may still
be able to call some property getters without them throwing exceptions
even after Dispose has been called on the object. That's because
property getters are usually nothing more than trivial wrappers around
instance variables.- Hide quoted text -

- Show quoted text -
Clear - thanks. I was confused Re the values in the components which
would be destroyed by dispose(bool) versus simple instance vars which
are freed when the form is garbage collected. We tend to use the word
destroy for both things which is a bit confusing.

Ta

Ray
Nov 26 '07 #14

P: n/a
On Nov 21, 12:26 pm, Peter Duniho <NpOeStPe...@NnOwSlPiAnMk.com>
wrote:
It is possible that the CLI _allows_ for early collection of
parameter-held references, and that the current implementation itself
just doesn't take advantage of that. But if so, the behavior is (I
think) more important than the theoretical possibility in this case,
since we're talking about what Application.Run() _does_, not what it
might do.
Maybe. I'm just thinking about theoretical possibilities that I could
not demonstrate in 1.1, but were a piece of cake in 2.0. At some
level you have to consider the possibility or risk hard to find bugs
when your code runs on a newer version of the framework.
>
Obviously, a parameter can be collected during the execution of an
unmanaged function.

Based on what I've seen, I'm not convinced of that. Even when there's
no actual use of the parameter in a method, the object referenced by it
is apparently not collectable until the method returns. It wouldn't
matter whether you called a managed or unmanaged function.
Yeah, after some more thought I think you're right. The interop
marshaler would likely prevent the reference from being eligible until
the function returns. Asynchronous functions and functions that
accept say...an IntPtr to a managed object would still be problematic.
That's the most important reason for the
existence of GC.KeepAlive.

I'm not sure I'd rank the reasons in that way, but I'm not willing to
quibble about which is the _most_ important. Clearly you need
GC.KeepAlive() any time you need to avoid early collection of
references that aren't explicitly used later in the method. There are
lots of different ways to run into the issue, and calling an unmanaged
function is just one example.

But if you want that to be the most important, that's okay by me. :)
No, you are right. I should be careful about ranking things like
that. There certainly are other reasons for it's use. A scenario
involving an unmanaged function just happened to be the only time I've
used it :)

Nov 26 '07 #15

P: n/a
On 2007-11-26 05:55:53 -0800, rbrowning1958 <RB***********@gmail.comsaid:
I'm not familiar with the difference between a weak and a strong
reference.
You don't really need to be. As far as garbage collection is
concerned, a weak reference isn't a reference at all, while a strong
reference is just a normal reference like what you're accustomed to.
The way my simple mind works would lead me to believe that
a form's
constructor adds itself to the application.openForms list, and the
dispose(bool) thing would remove it from that list, making it eligible
for garbage collection as long as nothing else references the form.
That's not quite correct. A form is added to the open forms list when
it's shown, and removed when it's hidden. Simply constructing the form
doesn't add it, and it can be removed from the list without disposing
the form.
Since application.run is instantiating a form then its constructor
adds it to applcation,openforms thereby keeping it alive even if there
is no other variable referencing it. Am I missing something?
Application.Run() shows the form, and since it must maintaing the
reference itself until that point, you're assured the GC won't collect
the form before that point. After that point, the shown form is in the
open forms list and thus also won't be collected.

IMHO, the important thing here is that the system does work and forms
won't be collected prematurely, assuming you use the normal idioms in
..NET. You can, of course, manage your forms in some obfuscated way
that does manage to prematurely release a form, but you'd have to go
out of your way to do that (for example, showing the form outside the
normal Application.Run() mechanism, and storing the reference in a
WeakReference instance).

In any case, as long as the form is visible on the screen, it will not
be collected.

Pete

Nov 26 '07 #16

P: n/a
"Brian Gideon" <br*********@yahoo.comwrote in message
news:5a**********************************@g30g2000 hsb.googlegroups.com...
>Based on what I've seen, I'm not convinced of that. Even when there's
no actual use of the parameter in a method, the object referenced by it
is apparently not collectable until the method returns. It wouldn't
matter whether you called a managed or unmanaged function.

Yeah, after some more thought I think you're right. The interop
marshaler would likely prevent the reference from being eligible until
the function returns. Asynchronous functions and functions that
accept say...an IntPtr to a managed object would still be problematic.
I just tested this because I was pretty sure you were wrong but you are in
fact correct. When passing an instance of a class into an unmanaged function
I couldn't get it to dispose of the object while it was in the function.
Code is below if you want to test.

C++ code:
#include "stdafx.h"
#include "DelMeDll.h"

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

typedef int __stdcall SomeCallback(int Count);

// This is an example of an exported function.
int __stdcall DoIt(void* CallbackPtr, void* SomeClass)
{
SomeCallback* sc = (SomeCallback*)CallbackPtr;
for(int i = 0; i < 10; i++)
{
sc(i);
}
return 42;
}
C# code

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

using System.Runtime.InteropServices;

namespace DelMeCallDLL

{

public delegate int CallbackDelegate(int Count);

public class Form1 : System.Windows.Forms.Form

{

private System.Windows.Forms.Button button2;

private System.Windows.Forms.Button button1;
[DllImport("C:\\Stuff\\DelMeDll\\Debug\\DelMeDll.dl l")]

static extern int DoIt(CallbackDelegate CallBack, SomeClass MyClass);

public Form1()

{

InitializeComponent();

}

#region Windows Form Designer generated code

private void InitializeComponent()

{

this.button1 = new System.Windows.Forms.Button();

this.button2 = new System.Windows.Forms.Button();

this.SuspendLayout();

//

// button1

//

this.button1.Location = new System.Drawing.Point(104, 80);

this.button1.Name = "button1";

this.button1.Size = new System.Drawing.Size(80, 80);

this.button1.TabIndex = 0;

this.button1.Text = "button1";

this.button1.Click += new System.EventHandler(this.button1_Click);

//

// button2

//

this.button2.Location = new System.Drawing.Point(192, 208);

this.button2.Name = "button2";

this.button2.Size = new System.Drawing.Size(64, 48);

this.button2.TabIndex = 1;

this.button2.Text = "button2";

this.button2.Click += new System.EventHandler(this.button2_Click);

//

// Form1

//

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(292, 266);

this.Controls.Add(this.button2);

this.Controls.Add(this.button1);

this.Name = "Form1";

this.Text = "Form1";

this.ResumeLayout(false);

}

#endregion

[STAThread]

static void Main()

{

Application.Run(new Form1());

}

private void button1_Click(object sender, System.EventArgs e)

{

DoIt(new CallbackDelegate(this.Callback), new SomeClass());

}

private int Callback(int Count)

{

GC.Collect();

Console.WriteLine(Count.ToString());

return Count;

}

private void button2_Click(object sender, System.EventArgs e)

{

GC.Collect();

}

}

}
Nov 26 '07 #17

P: n/a
On 26 Nov, 18:08, Peter Duniho <NpOeStPe...@NnOwSlPiAnMk.comwrote:
On 2007-11-26 05:55:53 -0800,rbrowning1958<RBrowning1...@gmail.comsaid:
I'm not familiar with the difference between a weak and a strong
reference.

You don't really need to be. As far as garbage collection is
concerned, a weak reference isn't a reference at all, while a strong
reference is just a normal reference like what you're accustomed to.
The way my simple mind works would lead me to believe that
a form's
constructor adds itself to the application.openForms list, and the
dispose(bool) thing would remove it from that list, making it eligible
for garbage collection as long as nothing else references the form.

That's not quite correct. A form is added to the open forms list when
it's shown, and removed when it's hidden. Simply constructing the form
doesn't add it, and it can be removed from the list without disposing
the form.
Since application.run is instantiating a form then its constructor
adds it to applcation,openforms thereby keeping it alive even if there
is no other variable referencing it. Am I missing something?

Application.Run() shows the form, and since it must maintaing the
reference itself until that point, you're assured the GC won't collect
the form before that point. After that point, the shown form is in the
open forms list and thus also won't be collected.

IMHO, the important thing here is that the system does work and forms
won't be collected prematurely, assuming you use the normal idioms in
.NET. You can, of course, manage your forms in some obfuscated way
that does manage to prematurely release a form, but you'd have to go
out of your way to do that (for example, showing the form outside the
normal Application.Run() mechanism, and storing the reference in a
WeakReference instance).

In any case, as long as the form is visible on the screen, it will not
be collected.

Pete
Pete,

<<That's not quite correct. A form is added to the open forms list
when
it's shown, and removed when it's hidden. Simply constructing the
form
doesn't add it, and it can be removed from the list without disposing
the form.>>
I don't think that's quite correct - but what do I know? What my tests
show is that the form is not removed from application.openForms when a
form is hidden. What's unusual though is it is not added to the
openForms list until it is shown. If you create the form but don't
display it it's not in the list. As soon as you show it it is added to
the list and not removed until the form is closed (close method or
clicking close button which I presume calls Dispose(bool)). I wonder
what happens when you do this:

Form2 form2;
form2 = new Form2();

i.e. declare and instantiate inside a routine. It's probably a
candidate for GC straight away - nothing references it and it's not
visible. It's not disposed(bool) though is it? If I did show it it
gets added to the application.forms list so there is a reference to
it.

So what's a "WeakReference instance"?

Best

Ray
Nov 28 '07 #18

P: n/a
On 21 Nov, 04:58, "Michael C" <m...@nospam.comwrote:
"Peter Duniho" <NpOeStPe...@NnOwSlPiAnMk.comwrote in message

news:2007112020512427544-NpOeStPeAdM@NnOwSlPiAnMkcom...
That doesn't tell you anything. As long as the reference is in the open
forms list (and of course it would be), the fact that the reference
remains valid until the function exits is meaningless.

No, I gave it a test with a regular class. The class would not be collected
until the function exited.
In fact, it's a given that the reference to the form would remain valid
until Application.Run() returns, because if that weren't true a forms
application would never work. By definition, the method returns when the
form is closed, so obviously the duration of the call to Application.Run()
and the lifetime of the form are _very_ closely tied to each other.

I wasn't talking about Application.Run at all. I was just using a regular
function that I defined myself and passed in an instance of a class I
defined. The only way I could get the class to be GCd before the function
exits was to set the parameter to null inside the function.
In other words, whatever test you did, all it accomplished was proving
that Application.Run() does in fact work. Which hopefully we all believed
already.

Rubbish.
There's no reason to believe that the collection of forms didn't exist
before. Just because it wasn't exposed to the application itself, that
doesn't mean it wasn't there.

That's true although that doesn't mean it did exist either.

Michael
Michael,

What I've found is that showing a form adds itself to
application.openForms, but hiding a modeless form does not remove it.
Surely the reason this works with Application.run is because that
shows the form, hence its referenced by application.openForms. Hiding
a modeless form doess seem to remove it from application.openForms
which kind of makes sense because closing it does not dispose it
therefore it needs to be removed from application.forms so it can be a
candidate for GC.

Ray
Nov 28 '07 #19

P: n/a
On 2007-11-28 06:39:13 -0800, rbrowning1958 <RB***********@gmail.comsaid:
<<That's not quite correct. A form is added to the open forms list
when
it's shown, and removed when it's hidden. Simply constructing the
form
doesn't add it, and it can be removed from the list without disposing
the form.>>
I don't think that's quite correct - but what do I know? What my tests
show is that the form is not removed from application.openForms when a
form is hidden.
I should have been more precise, especially given that you can hide a
form without closing it.

Closing a modal form doesn't dispose it; it just hides it. But doing
so is still sufficient for it to be removed from the open forms list.

But you're right, the important act is closing the form, not hiding it.
What's unusual though is it is not added to the
openForms list until it is shown. If you create the form but don't
display it it's not in the list. As soon as you show it it is added to
the list and not removed until the form is closed (close method or
clicking close button which I presume calls Dispose(bool)).
Right. Noting that for modal forms closing the form doesn't dispose it.
I wonder
what happens when you do this:

Form2 form2;
form2 = new Form2();

i.e. declare and instantiate inside a routine. It's probably a
candidate for GC straight away - nothing references it and it's not
visible.
That's correct.
It's not disposed(bool) though is it?
The finalizer will dispose it, eventually.
If I did show it it
gets added to the application.forms list so there is a reference to
it.
That's correct.
So what's a "WeakReference instance"?
WeakReference is a class. A WeakReference instance is an instance of
that class.

Pete

Nov 28 '07 #20

This discussion thread is closed

Replies have been disabled for this discussion.