about resources and the using

T

Tony Johansson

Hi!

GC removes objects when the GC decides so because C# is managed.
At the bottom I have a code snipped.
The book I read say Always call Dispose() on Pen objects or use the using
feature on the Pen object.
I mean C# is managed so I can't understand why I should dispose the Pen
object. GC should take care of this.
The reason is probably that I mixup memory and resources. GC take care of
free memory but not resources.
I have some problem to understand why I must dispose the Pen object here
because I see the Pen object as
any object such as a Person or Car.

So my first question is can I use the rule that say always dispose an object
where the class implements the IDisposable which actually mean that I have
to check if the class implements the IDisposable ?
My second question is if I don't dispose the Pen object will a lot of
resources be allocated that will affect the application and what kind of
resources is that ?
I don't think that the amount of resources is that limited. I mean that it
would have been a considerably different situation if I had to create many
,many Pen object but here I just create a single one.

protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
Pen blackPen = new Pen(Color.Black, 1);

if (ClientRectangle.Height / 10 > 0)
{
for (int y = 0; y < ClientRectangle.Height; y+=
ClientRectangle.Height/10)
{
g.DrawLine(blackPen, new Point(0,0), new
Point(ClientRectangle.Width,y));
}
}
}

//Tony
 
P

Patrice

GC removes objects when the GC decides so because C# is managed.
At the bottom I have a code snipped.
The book I read say Always call Dispose() on Pen objects or use the using
feature on the Pen object.
I mean C# is managed so I can't understand why I should dispose the Pen
object. GC should take care of this.

As you said if you let the GC do that, it will happen at a time out of your
control (possibly not before it is needed). By calling this explicitely (or
implicitely using "using") you'll control when it is done.
I have some problem to understand why I must dispose the Pen object here
because I see the Pen object as
any object such as a Person or Car.

A Pen also uses other resources so disposing a Pen does a bit more than just
releasing memory.
So my first question is can I use the rule that say always dispose an
object where the class implements the IDisposable which actually mean that
I have to check if the class implements the IDisposable ?

If the class have a Dispose or Close method, it's best to call it as soon as
you are done with the class...

To take a comparison, will you wait for your app to terminate to close a
file even if you don't ever need it any more. Likely not, you'll close the
file as soon as you are done with it.
My second question is if I don't dispose the Pen object will a lot of
resources be allocated that will affect the application and what kind of
resources is that ?
I don't think that the amount of resources is that limited. I mean that it
would have been a considerably different situation if I had to create many
,many Pen object but here I just create a single one.

A single one nut each time your code is called so at some point you could
have problems even if we are no more on Windows 3.1.

IMO it's not even worth to known. Either keep the same pen handy or properly
dispose it. You shouln't relly on knowing about how a paticular resource
behaves.

If I remember a tool such as
http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx should allow
to show how much handles you are consuiming. It would be also easy to create
a test app to see at whihc point you are stuck when creating Pens. Even if
the limit is high, IMO this is not a reason for letting things being
uncontrolled...
 
A

Alberto Poblacion

Tony Johansson said:
Pen blackPen = new Pen(Color.Black, 1);

A suggestion: if instead of the quoted line you do the following:

Pen blackPen = Pens.Black;

then you get a statically allocated pen and you don't have to worry
about disposing de pen. Otherwise, it is a good idea to Dispose it, because
you are doing the allocation inside the OnPaint method which could
potentially execute thousands of times, so you would be wasting thousands of
pens before the GC runs.
 
T

Tony Johansson

Alberto Poblacion said:
A suggestion: if instead of the quoted line you do the following:

Pen blackPen = Pens.Black;

then you get a statically allocated pen and you don't have to worry
about disposing de pen. Otherwise, it is a good idea to Dispose it,
because you are doing the allocation inside the OnPaint method which could
potentially execute thousands of times, so you would be wasting thousands
of pens before the GC runs.

Very good point

//Tony
 
T

Tony Johansson

Alberto Poblacion said:
A suggestion: if instead of the quoted line you do the following:

Pen blackPen = Pens.Black;

then you get a statically allocated pen and you don't have to worry
about disposing de pen. Otherwise, it is a good idea to Dispose it,
because you are doing the allocation inside the OnPaint method which could
potentially execute thousands of times, so you would be wasting thousands
of pens before the GC runs.

Hi!

I have changed a little just to test the amout of resources that I have when
creating a lot of Pen object.
I hid and show the screen so this OnPaint overridden method was called 10
times and I didn't notice any kind resource problem.
Notice also that each call to the OnPaint will create 100000 Pen object in
the for loop.
So the amount of resources seems to be almost infinite.

So according to my calculations I created 1000000 Pen object without any
kind of resource problem what so ever.
Can somebody give me a comment about this test ?

Protected override void OnPaint(PaintEventArgs e)
{
Console.WriteLine("i= {0}", count++);
GraphicsPath path = new GraphicsPath();

Graphics g = e.Graphics;
Pen blackPen = new Pen(Color.Black,1);
for (int i = 0; i < 100000; i++)
{
blackPen = new Pen(Color.Black, 1);
}

if (ClientRectangle.Height / 10 > 0)
{
for (int y = 0; y < ClientRectangle.Height; y +=
ClientRectangle.Height / 10)
{
g.DrawLine(blackPen, new Point(0, 0), new
Point(ClientRectangle.Width, y));
}
}
}
 
J

Jeff Johnson

Pen blackPen = new Pen(Color.Black, 1);

I just want to mention something here: if it is your intention to create a
pen which will draw lines exactly one pixel in size, this is not the correct
way to do it. A size of 1 could, believe it or not, cause lines greater than
1 pixel wide to be drawn. To get exactly 1 pixel, use -1 for the size
argument. This is documented in the Pen's constructor.
 
P

Patrice

It's possible that not using a pen or creating a pen with always the same
characteristics is optimized or even that limitations in previous OS are
gone.

As I said earlier IMO it doesn't matter as testing each and every disposable
resource and relying on their indiviual behavior is not doable in practice.

IMO if a resource is disposable, just dispose it.
 
P

Peter Duniho

Patrice said:
[...]
I have some problem to understand why I must dispose the Pen object
here because I see the Pen object as
any object such as a Person or Car.

A Pen also uses other resources so disposing a Pen does a bit more than
just releasing memory.

In particular, some important points those "other resources":

In most cases, when an object implements IDisposable, it's because
either it owns other IDisposable objects, or it itself owns _unmanaged_
resources.

..NET currently only manages memory. But one can imagine a .NET that
manages other resources as well, such as file objects, network socket
objects, COM objects, etc. In such a utopian world, we wouldn't need
IDisposable.

But we aren't in that utopian world. And since there are resources on
the computer other than memory, and since .NET manages only the memory
resource, we need a way to help .NET out when it comes to knowing when
those resources are no longer needed.

The other problem with those resources, besides the fact that .NET has
no way to track them and know when they are ready to be released and
whether the system is running low on them, is that they are much scarcer
resources than memory. Because of the way the OS uses them, for a
variety of reasons you can can run out of many of those resources faster
than you can run out of memory.

Without IDisposable, .NET could refrain from releasing those resources
for a much longer time than is warranted, because not only does it not
realize they even exist, even if it did, it has no way to know whether
it's a good time to start release them (either because the system is
running low, or because there's a good point in execution to take the
time to release the unused ones).
If the class have a Dispose or Close method, it's best to call it as
soon as you are done with the class...

To be clear though: it is usually possible to know when writing the code
that an object implements IDisposable.

It's not necessary to have a check in the code for IDiposable (e.g.
"IDisposable disposable = myObject as IDisposable; if (disposable !=
null) disposable.Dispose();"). You just have to read the documentation
and make sure the object is disposed of in code when the code is done
with it (usually this can be done with "using"…but for objects that have
to live longer than a single block of code, of course you'll have to do
it explicitly).

Pete
 

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