When should I use 'using' ?

  • Thread starter Thread starter Cybertof
  • Start date Start date
C

Cybertof

Hi !

I'm wondering about the use of the 'using' statement.
In a procedure, should i declare all instance variables in a using
clause ?

In the below code, what would happen if MyFont & MyFont2 would be
declared in the body of the Main() and not inside the using (even not
referenced in the using) ? Would be there something to call to dispose
them ?

I thought the garbage collector was doing all this by itself...



***********
code sample
***********
using System.Drawing;
class a
{
public static void Main()
{
using (Font MyFont = new Font("Arial", 10.0f), MyFont2 = new Font
("Arial", 10.0f))
{
// use MyFont and MyFont2
} // compiler will call Dispose on MyFont and MyFont2

Font MyFont3 = new Font("Arial", 10.0f);
using (MyFont3) // WHAT HAPPEN IF no using here ???
{
// use MyFont3
} // compiler will call Dispose on MyFont3

}
}





Regards,
Cybertof.
 
Cybertof, if you the using block in this case is taking care of calling the
Dispose method as you have indicated. If you didn't use the using statement
in your second code section you would just have to call Dispose yourself.
In that case you should wrap the Font creation and use in a try...
finally... block to ensure that your Font is Disposed properly. I would
recommend the using statement though since it takes care of making sure your
object is cleaned up. Does that answer your question?
 
Yes, but so i have another question :
What happens if i don't use 'using' at all in the following code :

public void Test()
{
MessageBox.Show("Before");
Font MyFont = new Font("Arial", 10.0f);
MessageBox.Show("After");
}

MyFont is never released ?
Does it mean that if you instanciate an object from a class in a
procedure body, the object is never cleaned ?
I thought the garbage collector was doing it...
So should i call .Dispose() on every instance i would create from system
classes or homemade classes ?


Regards,
Cybertof.
 
MyFont will be released at the leisure of the GC. Possibly when the program
closes. You won't get a leak and for the example you cite performance will
not be important.

If you do a lot of drawing or use a lot of fonts or just want to be a good
programmer call Dispose() on all objects that support IDisposable.

The object finalizer which is called by the GC will ( *should* ) call
Dispose when it gets collected but unless you call GC.Collect specifically,
you have no control over the process.

Personally, I never use using{ .... } I guess its a style choice.

--
Bob Powell [MVP]
C#, System.Drawing

September's edition of Well Formed is now available.
http://www.bobpowell.net/currentissue.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/gdiplus_faq.htm
 
So i'm in front of a big question :

Does the ArrayList.Add() method just add a reference to the object added
or the object is copied ?
The answer seems 'reference' as if i do the following code i get the
same content for everyobject added :

So let's consider the following code :

// i'm in a class constructor
foreach (DataRow dataRow in dataTable.Rows)
{
CLockeInstrument myInstrument=new CLockeInstrument(dataRow);
MyArrayList.Add(myInstrument);
}

//Notes :
//- The constructor initialise the instance with columns of the dataRow.
//- MyArrayList is an ArrayList declared in my Class


If outside the foreach i 'dispose' the myInstrument object,
what happens to the ArrayList content ?
(note that myInstrument instance may not exist anymore outside the
constructor, and the private class memeber MyArrayList will...)
 
Cybertof said:
So i'm in front of a big question :

Does the ArrayList.Add() method just add a reference to the object added
or the object is copied ?

The reference is copied.
The answer seems 'reference' as if i do the following code i get the
same content for everyobject added :

So let's consider the following code :

// i'm in a class constructor
foreach (DataRow dataRow in dataTable.Rows)
{
CLockeInstrument myInstrument=new CLockeInstrument(dataRow);
MyArrayList.Add(myInstrument);
}
Okay.

//Notes :
//- The constructor initialise the instance with columns of the dataRow.
//- MyArrayList is an ArrayList declared in my Class


If outside the foreach i 'dispose' the myInstrument object,

Which myInstrument object? You're creating and adding lots of them.
what happens to the ArrayList content ?

The object is disposed, but the reference is still to a live object -
it's just that you can't do anything with it without getting an
exception.
(note that myInstrument instance may not exist anymore outside the
constructor, and the private class memeber MyArrayList will...)

I think you need to be very clear about the difference between
instances and variables. A variable can hold a reference to an
instance, but it isn't an instance itself.
 
Mr.Tickle,

To be more strict one can't leek unmanaged resources either if the class is
carefully designed and implemented (classes in the framework has to be so,
but some of them are not) . If the class holds unmanaged resources it has to
have *Finalize* method declared. Actually it doesn't have to, but this is by
dispose pattern. The *Finalize* method has to call Dispose and free the
unmanaged resources.
In this case the unmanaged resources are even released before the memory is
garbage collected (the memory will be collected on the next GC request.)

B\rgds
100
 
Thats a big IF, and we all know how well people handle resources.

Just about as well as they can parse strings.
 
Congrats for your new title :-)

José
Jon Skeet said:
The reference is copied.


Which myInstrument object? You're creating and adding lots of them.


The object is disposed, but the reference is still to a live object -
it's just that you can't do anything with it without getting an
exception.


I think you need to be very clear about the difference between
instances and variables. A variable can hold a reference to an
instance, but it isn't an instance itself.
 
Anyway, Dispose has to be called as soon as the object is no longer in use.
When holding unmanaged resource actually we hold memory which cannot be
used. I haven't heard anybody run out of handlers, but I have heard people
run out of memory because of that.
However most of the classes are not disposable. Normally programmers don't
write disposable types. Prgrammers who writes them, though, has to be
perfectly familiar with dispose pattern. So I assuming that all disposable
types are correctly written. That's why I dare to say that we have resource
leaks as much as we have memory leaks.

Or at least I hope so :)

B\rgds
100
 
I'm not sure the ArrayList.Add() method make a copy of the object passed
to it

For example in this case :

CLockeInstrument myInstrument=new CLockeInstrument();
foreach (DataRow dataRow in dataTable.Rows)
{
MyInstrument.FillFromDataRow(dataRow);
MyArrayList.Add(myInstrument);
}

In this case, MyInstrument is not declared as 'new' in each loop,
and at the end, i get a full MyArrayList will all the same instruments
pointing to the same instance (the last one beeing affected in
MyInstrument).
If the MyArrayList.Add() would make copy, the subsequent call to
MyInstrument.FillFromDataRow(dataRow) would not affect previous items
from the ArrayList.

No ?
 
Cybertof said:
I'm not sure the ArrayList.Add() method make a copy of the object passed
to it

It doesn't. It makes a copy of the *reference*, as I said.
For example in this case :

CLockeInstrument myInstrument=new CLockeInstrument();
foreach (DataRow dataRow in dataTable.Rows)
{
MyInstrument.FillFromDataRow(dataRow);
MyArrayList.Add(myInstrument);
}

In this case, MyInstrument is not declared as 'new' in each loop,
and at the end, i get a full MyArrayList will all the same instruments
pointing to the same instance (the last one beeing affected in
MyInstrument).

Yes. You get lots of copies of the same reference.
If the MyArrayList.Add() would make copy, the subsequent call to
MyInstrument.FillFromDataRow(dataRow) would not affect previous items
from the ArrayList.

No ?

Yes, but as I said, it's not copying the *object*, it's copying the
*reference*. It's very important that you understand how reference
types and value types work - I've got a couple of articles which deal
with this tangentially, and might help you.

http://www.pobox.com/~skeet/csharp/parameters.html
http://www.pobox.com/~skeet/csharp/memory.html
 
Hello Jon,

Thanks for your articles.

When declaring something like

public void Test()
{
CMyClass MyClassInstance = new CMyClass();
}

If I understand what your are saying, this line creates a new object on
the Heap (the object is an instance of CMyClass) and the variable
MyCalssInstance contains the reference to that object.
Am i right ?

Now, my 2 question is :
1- How (and when) is the object on the heap created ?
2- How (and by who) should this object be distroyed ?

For the 3rd question (and last one i hope), let's go back to my previous
sample :

foreach (DataRow dataRow in dataTable.Rows)
{
CLockeInstrument myInstrument=new CLockeInstrument(dataRow);
MyArrayList.Add(myInstrument);
}

This code creates 'on the fly' instances of the CLockeInstrument class,
each beeing reference in the variable myInstrument.
But, each time the loop is performed, the variable is overwritten by a
new reference to a new object on the heap.
Then, i'm in the case of that i have lost all my references (apart of
those beeing stored in the MyArrayList.
So, when all the objects (on the heap) will be destroyed ?

Does the ArrayList contains the object itselves (a copy) or a list of
references to objects on the heap ?


Regards,
Cybertof.
 
Cybertof said:
Thanks for your articles.

When declaring something like

public void Test()
{
CMyClass MyClassInstance = new CMyClass();
}

If I understand what your are saying, this line creates a new object on
the Heap (the object is an instance of CMyClass) and the variable
MyCalssInstance contains the reference to that object.
Am i right ?
Yes.

Now, my 2 question is :
1- How (and when) is the object on the heap created ?

It's created by you calling new CMyClass(), and it's created at that
point.
2- How (and by who) should this object be distroyed ?

If it doesn't contain any unmanaged resources, the memory it occupies
will be released at some point after there are no "live" variables
which reference it (directly or indirectly) by the garbage collector,
and that's fine.

If it contains unmanaged resources, you should implement IDisposable so
that those resources can be explicitly released, but the memory for the
object itself will still be in the hands of the garbage collector.
For the 3rd question (and last one i hope), let's go back to my previous
sample :

foreach (DataRow dataRow in dataTable.Rows)
{
CLockeInstrument myInstrument=new CLockeInstrument(dataRow);
MyArrayList.Add(myInstrument);
}

This code creates 'on the fly' instances of the CLockeInstrument class,
each beeing reference in the variable myInstrument.
But, each time the loop is performed, the variable is overwritten by a
new reference to a new object on the heap.
Then, i'm in the case of that i have lost all my references (apart of
those beeing stored in the MyArrayList.
So, when all the objects (on the heap) will be destroyed ?

They will only be eligible for garbage collection when either their
"slots" in the ArrayList are replaced, or the ArrayList itself is
eligible for garbage collection.
Does the ArrayList contains the object itselves (a copy) or a list of
references to objects on the heap ?

It contains a list of references.
 
How do you make an ArrayList eligible for garbage collection ?

1/ MyArrayList.Clear();
2/ MyArrayList.Dispose();
3/ set MyArrayList = (ArrayList) null;

I think the 2/ is not the good answer as, if i understand, an ArrayList
is a managed ressource, and so should be taken care by the garbage
collector.

Also 3/ sounds to me strange but i don't know why.
Is this syntax correct to do something ?


Cybertof.
 
Cybertof said:
How do you make an ArrayList eligible for garbage collection ?

1/ MyArrayList.Clear();

No - that just removes the contents of the array list - ie the contents
become eligible for garbage collection (if there aren't any other
references to each object previously referred to in the list), but the
array list itself doesn't.
2/ MyArrayList.Dispose();

No - ArrayList doesn't implement IDisposable.
3/ set MyArrayList = (ArrayList) null;

There's no need to cast here, and if MyArrayList is a local variable
there's no need to do anything at all - and the same goes for if it's
an instance variable and the instance that it's a part of becomes
eligible for garbage collection. Of course, if there are any *other*
references to the array list anywhere, it won't become eligible.

Most of the time you don't need to explicitly set things to null - when
you no longer need something, it tends to naturally become eligible for
garbage collection, just due to the structure of the program.
 
Back
Top