Dispose method

  • Thread starter Thread starter web1110
  • Start date Start date
W

web1110

If I have 2 variables, A and B, referencing the same object and then do a
A.Dispose(), what happens to B?
 
Hi y'all.

After looking in to this, I better elaborate.

I have a control object. It operates it 2 modes:

A. It can display itself. The display handled by a control display
manager.

B. It can be utilized without being displayed.

Now, the situation I am confused about is as follows:

A. I instantiate such a object.
B. I give it to the control manager to display.
C. When the user is done, the control manager (which keeps a reference to
the control in a stack) disposes of its copy.
D. However, the class that instantiated the control in the first place
wants to keep the object present for additional reference.

What happens to the original object after the control manager disposes of
its version?

Thanx,
Bill
 
Another add on.

When the control manager pops a control from its stack, it does a dispose on
that reference.

Now, if instead, it simply popped the reference without doing the dispose
and then over wrote the stack entry with another control, does the over
written entry get dereferenced.

ie

Stack control A at index 0
Stack control B at index 1
Stack control C at index 2
Pop index 2 - actually, do nothing, hust decrement to top of stack pointer.
Stack control D at index 2

Is C recognized as no longer being referenced or is a dispose manditory?
 
web1110 said:
Hi y'all.

After looking in to this, I better elaborate.

I have a control object. It operates it 2 modes:

A. It can display itself. The display handled by a control display
manager.

B. It can be utilized without being displayed.

Now, the situation I am confused about is as follows:

A. I instantiate such a object.
B. I give it to the control manager to display.

This would seem to be the critical point.

Are you giving it a reference (handle) to the object or the object itself?
 
re your question, I am assigning the object itself.

I call the control manager with

CLControlManager.vdDisplayControl(theControl);

In CLControlManager, I save the control with

ControlStack[ix]=thePassedCotrol;
 
You question makes no sense.

You always pass around references to objects - you cannot pass an object by value.

As far as the OP's question is concerned you have entered a world of pain that IDisposable does not cope with. For IDisposable to work correcctly there has to be a strong notion of ownership of the object. You only have four options really:

1. Decide who is going to take responsibility for calling Dispose and stick to that architecturally
2. Let the finalizer talke care of releasing resources and don't call Dispose at all
3. Implement some form of reference counting architecture where everone "releases" their reference (calling a method) and then the object Disposes itself when the refcount goes to zero.
4. Clone the object before its passed to the controller so they each have an independent copy they can Dispose

As you can see, none of these is enormously attractive and some may be unsuitable for you architecture

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk
Hi y'all.

After looking in to this, I better elaborate.

I have a control object. It operates it 2 modes:

A. It can display itself. The display handled by a control display
manager.

B. It can be utilized without being displayed.

Now, the situation I am confused about is as follows:

A. I instantiate such a object.
B. I give it to the control manager to display.

This would seem to be the critical point.

Are you giving it a reference (handle) to the object or the object itself?

C. When the user is done, the control manager (which keeps a reference to
the control in a stack) disposes of its copy.
D. However, the class that instantiated the control in the first place
wants to keep the object present for additional reference.

What happens to the original object after the control manager disposes of
its version?

Thanx,
Bill

--
No virus found in this incoming message.
Checked by AVG Anti-Virus.
Version: 7.0.308 / Virus Database: 266.7.4 - Release Date: 18/03/2005



[microsoft.public.dotnet.languages.csharp]
 
Richard Blewett said:
You question makes no sense.

You always pass around references to objects - you cannot pass an object
by value.

As far as the OP's question is concerned you have entered a world of pain
that IDisposable does not cope with. For IDisposable to work correcctly
there has to be a strong notion of ownership of the object. You only have
four options really:

1. Decide who is going to take responsibility for calling Dispose and
stick to that architecturally

Doable but very error prone.
2. Let the finalizer talke care of releasing resources and don't call
Dispose at all

The object may not get cleaned up for a long time, which may cause
unanticipated side effects.

3. Implement some form of reference counting architecture where everone
"releases" their reference (calling a method) and then the object Disposes
itself when the refcount goes to zero.

You can use a wrapper class that implements the reference counting (isn't
that what an rcw does?).
4. Clone the object before its passed to the controller so they each have
an independent copy they can Dispose

That might be enormously expensive and may not even work (depends on what
the classes contain).

As a general approach I prefer option 3 - hide the object behind a wrapper
class. It all depends on the object itself and the application around it. I
don't think a single approach will solve all problems.
 
Agreed, thats why I said he has entered a world of pain.

and 3) is the best approach if you can guarantee not to get circular references. Although I do think 2) has merit if there really is no strong notion of ownership - granted all the issues about finalizers - but sometimes only the CLR has a real idea of when something can be cleaned up.

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk


Richard Blewett said:
You question makes no sense.

You always pass around references to objects - you cannot pass an object
by value.

As far as the OP's question is concerned you have entered a world of pain
that IDisposable does not cope with. For IDisposable to work correcctly
there has to be a strong notion of ownership of the object. You only have
four options really:

1. Decide who is going to take responsibility for calling Dispose and
stick to that architecturally

Doable but very error prone.
2. Let the finalizer talke care of releasing resources and don't call
Dispose at all

The object may not get cleaned up for a long time, which may cause
unanticipated side effects.

3. Implement some form of reference counting architecture where everone
"releases" their reference (calling a method) and then the object Disposes
itself when the refcount goes to zero.

You can use a wrapper class that implements the reference counting (isn't
that what an rcw does?).
4. Clone the object before its passed to the controller so they each have
an independent copy they can Dispose

That might be enormously expensive and may not even work (depends on what
the classes contain).

As a general approach I prefer option 3 - hide the object behind a wrapper
class. It all depends on the object itself and the application around it. I
don't think a single approach will solve all problems.
 
Richard Blewett said:
Agreed, thats why I said he has entered a world of pain.

Agreed in spades. I avoid sharing managed objects for that reason - one
class "owns" a resource and serializes or otherwise manages access to it.
and 3) is the best approach if you can guarantee not to get circular
references. Although I do think 2) has merit if there really is no strong
notion of ownership - granted all the issues about finalizers - but
sometimes only the CLR has a real idea of when something can be cleaned
up.

Very true.

I use a pattern where if there is either a Dispose or a finalizer I use both
unless. The only deviation is when there are thousands of objects and using
a finalizer would swamp the finalization queue (i.e. performance would
suck). I treat the Dispose interface as a contract, and if the client does
not call Dispose before the finalizer gets called I treat that as a program
error. Of course, this requires a strong degree of ownership, which brings
me back to my first principle - one object owns the resource.

regards,
Dave
 
Richard said:
You question makes no sense.

You always pass around references to objects - you cannot pass an object by value.


void test (object o)
{
object = Int32(5);
}


void test2()
{
object o = Int32(7);
test(o);

//so what is the value of o at this point? 7 or 5 ?

}

http://www.c-sharpcorner.com/Code/2005/Feb/Willswapwork.asp

"C# does manipulate objects by reference, and all object variables are
references. On the other hand, C# does not pass method arguments by
reference; it passes them by value, (even if the method arguments are of
reference type)."
 
Thank you all for your insight. I had a bad feeling 'bout this.

The object that invokes the control manager has the responsibility of
instantiationg the control and using it. One option is displaying it.
Hence, the control manager will never be the sole owner of the control.
Also, when the CLControlmanager is told to close the control window, the
instantiating object will still be in possession of the control and can
continue operating on the control. .

I think that the best solution would be NOT dispose of the control in the
CLContolManager class at all and leave that up to the instantiating class.

The thought process that led me down this disposing route was the references
to the control maintained in the CLControlmanager stack. I was thinking
that the CLR would consider the stack entry another independent reference.
It really isn't. At the time the instantiating class is finished with the
control, the CLControlManager will have closed the display according to the
rules of the game.

If, and this is not the situation, the instantiating objects control were go
go out of scope, the CLR would not know about the reference to the control
on the CLControlManager stack and this would cause problems when
CLControlManager tried to play with it.

A general question comes to mind.

A. I instantiate a control
B. CLControlManager displays it and puts it on its stack.
C. Things happen
D. The CLControlManager overwrites the stack entry to the control.
E. The instantiating object finishes with the control.

Step D will not have any effect on the control. It is still the
responsibility of the instantinating object. Is this correct?
 
Your example used pass by value Int32's. The situation is more like this:

public class mgr
{
private System.Windows.Forms.Button[] stk=new
System.Windows.Forms.Button[10];

public void getref(System.Windows.Forms.Button i)
{
stk[0]=i;
}

public void print()
{
MessageBox.Show("stk[0]="+stk[0].Text);
}
}

private void button1_Click(object sender, System.EventArgs e)
{
mgr theMgr=new mgr();

System.Windows.Forms.Button theBtn=new System.Windows.Forms.Button();

theMgr.getref(theBtn);

theBtn.Text="Hello";
MessageBox.Show("theBtn="+theBtn.Text); // Displays 'Hello'
theMgr.print(); // Displays
'Hello'

theBtn.Text="Goodbye";
MessageBox.Show("theBtn="+theBtn.Text); // Displays 'Goodbye'
theMgr.print(); // Displays
'Goodbye'
}
 
Yes that is correct. The CLR only cares about outstanding reachable references when it does a GC so overwriting a reference is unimportant. If you can be consistent with the control manager not Disposing (i.e. the creator always outlives the control manager) then making sure the creator is the one to dispose us the correct design IMO

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

Thank you all for your insight. I had a bad feeling 'bout this.

The object that invokes the control manager has the responsibility of
instantiationg the control and using it. One option is displaying it.
Hence, the control manager will never be the sole owner of the control.
Also, when the CLControlmanager is told to close the control window, the
instantiating object will still be in possession of the control and can
continue operating on the control. .

I think that the best solution would be NOT dispose of the control in the
CLContolManager class at all and leave that up to the instantiating class.

The thought process that led me down this disposing route was the references
to the control maintained in the CLControlmanager stack. I was thinking
that the CLR would consider the stack entry another independent reference.
It really isn't. At the time the instantiating class is finished with the
control, the CLControlManager will have closed the display according to the
rules of the game.

If, and this is not the situation, the instantiating objects control were go
go out of scope, the CLR would not know about the reference to the control
on the CLControlManager stack and this would cause problems when
CLControlManager tried to play with it.

A general question comes to mind.

A. I instantiate a control
B. CLControlManager displays it and puts it on its stack.
C. Things happen
D. The CLControlManager overwrites the stack entry to the control.
E. The instantiating object finishes with the control.

Step D will not have any effect on the control. It is still the
responsibility of the instantinating object. Is this correct?








--
No virus found in this incoming message.
Checked by AVG Anti-Virus.
Version: 7.0.308 / Virus Database: 266.7.4 - Release Date: 18/03/2005



[microsoft.public.dotnet.languages.csharp]
 
Richard Blewett said:
You always pass around references to objects - you cannot pass an object by value.

This leads me to a question.

Since .NET objects are reference types (and are therefore always passed by reference), is there any advantage to explicitly declaring and passing objects as "ref"?

In other words, is there any advantage to writing

void SomeMethod(ref object o) { /* ... */ }
// ...
SomeMethod(ref someObject);

versus:

void SomeMethod(object o) { /* ... */ }
// ...
SomeMethod(someObject);

?

Thanks,
Alex.
 
John Bailo said:
void test (object o)
{
object = Int32(5);
}


void test2()
{ object o = Int32(7);
test(o);

//so what is the value of o at this point? 7 or 5 ?

}

After making the necessary changes:



static void test (object o)
{
o = 5;
}

....

object o = 7;

the value should be 7, but what does it prove?
You are passing a reference by value, that is the callee gets a copy of the
value of the reference NOT a copy the actual object value.
The callee creates a new instance (boxed value 5) and assigns the reference
to the reference passed in as argument.
On return the callers object reference and the value are never touched, so
the value is unchanged.

Schematically:
Caller:
object o = 7;
stack location 0x127568 contains 0xba1208 which ----> object
- object contains value 7
on call test(object o)
stack location 0x127568 contains 0xba1208 which ----> object
- object contains value 7
and (argument) 0x127564 contains 0xba1208 which ----> same object
Callee:
on o = 5;
stack location 0x127564 contains 0xba1224 which -----> object o
(new) - new object has value 5.

On return;
Stack unwinds and 0x127564 goes out of scope which makes the object it
points to eligible for GC.

stack location 0x127568 contains 0xba1208 which ----> object
- object contains value 7

Willy.
 
"Alex" <[email protected]> a écrit dans le message de (e-mail address removed)...

Since .NET objects are reference types (and are therefore always passed by
reference), is there any advantage to explicitly declaring and passing
objects as "ref"?

No, objects are reference types that are always passed by value unless you
declare a ref parameter.

The difference is that the ref parameter allows you to change the actual
object that is passed in, rather than just being able to change the
properties of the object with a non-ref parameter.

Joanna
 
John Bailo said:
void test (object o)
{
object = Int32(5);
}


void test2()
{
object o = Int32(7);
test(o);

//so what is the value of o at this point? 7 or 5 ?

}

7, because passing a reference by value isn't the same as passing a
value by reference.

See http://www.pobox.com/~skeet/csharp/parameters.html
http://www.c-sharpcorner.com/Code/2005/Feb/Willswapwork.asp

"C# does manipulate objects by reference, and all object variables are
references. On the other hand, C# does not pass method arguments by
reference; it passes them by value, (even if the method arguments are of
reference type)."

Exactly. That doesn't disagree with what Richard was saying at all.
Note that he *didn't* say that objects were passed *by* reference, he
said that references to objects were passed. Big difference.
 
Alex said:
This leads me to a question.

Since .NET objects are reference types (and are therefore always
passed by reference), is there any advantage to explicitly declaring
and passing objects as "ref"?

Your reasoning is flawed - there's a big difference between passing a
reference by value and passing a value by reference.

See http://www.pobox.com/~skeet/csharp/parameters.html

And yes, sometimes it is worth passing reference-type parameters by
reference.
 
I looked over your link and found it informative.

There is one refeence example in the link:
StringBuilder first = new StringBuilder();
StringBuilder second = first;
first.Append ("hello");
first = null;
Console.WriteLine (second);

How does GC know when the object is eligable for disposal? The instaniating
variable has dereferenced the object and another variable now exists. If
second dereferences the object so it is no longer in use, how is this
condition detected?

Thanx,
Bill
 
Hello Joanna,

Joanna Carter (TeamB) said:
"Alex" <[email protected]> a écrit dans le message de (e-mail address removed)...

Since .NET objects are reference types (and are therefore always passed by
reference), is there any advantage to explicitly declaring and passing
objects as "ref"?

No, objects are reference types that are always passed by value unless you
declare a ref parameter.

That's what I meant.
Saying that the reference to the object is passed by value is the same as saying that the object itself is passed by reference.

What I did not know is whether there are benefits to passing the reference by reference (apart from being able to change it so it references another object).
The difference is that the ref parameter allows you to change the actual
object that is passed in, rather than just being able to change the
properties of the object with a non-ref parameter.

Is that the only benefit?

The reason that I'm asking is that I see a lot of C# code on the net that passes object references by reference to functions that do not change the reference (but may change the objects themselves). I thought that I may be missing something...

Thanks,
Alex.
 
Back
Top