Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / September 2007

Tip: Looking for answers? Try searching our database.

C# compiler option to find classes that implement IDisposable

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Carl Johansson - 24 Sep 2007 11:32 GMT
Being quite new to C#, I may have misunderstood this. If so please bear with
me!

As far as I can understand, any instances of a class that implements the
IDisposable interface must call the Dispose method not create leaks of
resources!? This can be accomplished by explicitly calling Dispose or
through the "using" statement.

For example, a recursive method that creates hundreds or thousands of
instances of, for example, OleDbConnection, OleDbCommand, and
OleDbDataReader, would eventually cause havoc unless they were explicitly
disposed through the Dispose method or the using statement, right?

Now, if all of the above is true, what is the easiest way to identify all
classes the implement the IDisposable interface? The "Auto list members"
pop-up window i VS will show the Dispose method if it is present, but then I
must always be alert, and that, I am not! Is it possible to get the C#
compiler to generate warning messages about these classes when used?

Best Regards Carl Johansson
Jon Skeet [C# MVP] - 24 Sep 2007 11:40 GMT
On Sep 24, 11:32 am, "Carl Johansson"
<carl.johans...@nogarbagehallde.com> wrote:
> Being quite new to C#, I may have misunderstood this. If so please bear with
> me!
[quoted text clipped - 3 lines]
> resources!? This can be accomplished by explicitly calling Dispose or
> through the "using" statement.

No, the instances don't call Dispose - the *clients* of those classes
call Dispose.
That doesn't mean it's always cut-and-dried as to where things should
be disposed. For instance, if you create a Stream and pass it into
Image.FromStream, you need to leave the stream open - image will close
it when the image is disposed.

> For example, a recursive method that creates hundreds or thousands of
> instances of, for example, OleDbConnection, OleDbCommand, and
> OleDbDataReader, would eventually cause havoc unless they were explicitly
> disposed through the Dispose method or the using statement, right?

Yes.

> Now, if all of the above is true, what is the easiest way to identify all
> classes the implement the IDisposable interface? The "Auto list members"
> pop-up window i VS will show the Dispose method if it is present, but then I
> must always be alert, and that, I am not! Is it possible to get the C#
> compiler to generate warning messages about these classes when used?

No - because you don't always want to dispose of something in the same
place you create it.

I'm afraid you basically have to be disciplined about it.

Jon
james - 24 Sep 2007 13:39 GMT
Carl,

The objects dispose themselves when they are memory collected.
Nothing tricky... its part of the design pattern.  For
OleDbConnection, an ancestor has

~Component()
{
   this.Dispose(false);
}

and Dispose is virtual.

You should call Dispose on IDisposables when you are finished because
it might be a while before the memory collector runs, but forgetting
will not cause "havoc".

-James
Jon Skeet [C# MVP] - 24 Sep 2007 14:33 GMT
> The objects dispose themselves when they are memory collected.

You should almost *never* rely on this, however. If something
implements IDisposable, you should call Dispose when you're done with
it.

The finalizer is merely a "belt and braces" approach in case you
forget to explicitly dispose things.

<snip>

> You should call Dispose on IDisposables when you are finished because
> it might be a while before the memory collector runs, but forgetting
> will not cause "havoc".

Um, it could do. If you forget to close connections explicitly, you
could end up running out of connections unnecessarily. Likewise not
disposing of a FileStream could stop you from then reopening the file
for writing.
This is also non-deterministic - so reproducing this issue reliably
could almost impossible.

Personally, I count that as "havoc"...

Jon
james - 24 Sep 2007 15:13 GMT
Jon,

I was trying to say that for someone just learning C# they don't need
to obsess over finding every IDisposable.

If you use the wizards in Visual Studio you can write an database
application without writing much code, and the worst thing would be to
kludge in calling Dispose everywhere because you aren't sure if the
generated code does that.

-James
Jon Skeet [C# MVP] - 24 Sep 2007 15:16 GMT
> I was trying to say that for someone just learning C# they don't need
> to obsess over finding every IDisposable.

Well, I think it's a good idea to be aware of it right from the start,
and try to build up an understanding of what implements IDisposable,
calling it appropriately. Best not to get into bad habits, IMO. I've
seen far too much code which calls Stream.Close() explicitly without
using a finally block etc - if you get into the habit of using a
"using" statement where appropriate, you don't end up with code like
that.

> If you use the wizards in Visual Studio you can write an database
> application without writing much code, and the worst thing would be to
> kludge in calling Dispose everywhere because you aren't sure if the
> generated code does that.

Well, that would certainly be bad - but so would saying, "Oh, it's
okay - the finalizer will take care of it."
The latter will lead to hard-to-reproduce bugs.

Jon
Doug Semler - 25 Sep 2007 01:52 GMT
> Jon,
>
> I was trying to say that for someone just learning C# they don't need
> to obsess over finding every IDisposable.

I disagree.  That's like saying that someone just learning C++ doesn't need
to worry about what the "virtual" keyword on a destructor declaration means.

Signature

Doug Semler, MCPD
a.a. #705, BAAWA.  EAC Guardian of the Horn of the IPU (pbuhh).
The answer is 42; DNRC o-
Gur Hfrarg unf orpbzr fb shyy bs penc gurfr qnlf, abbar rira
erpbtavmrf fvzcyr guvatf yvxr ebg13 nalzber. Fnq, vfa'g vg?

Brian Gideon - 25 Sep 2007 02:47 GMT
> > Jon,
>
[quoted text clipped - 5 lines]
>
> --

I don't know...I mean since James used the word obsess I can't
disagree too much.  Afterall, if you obsessed over *every* little
detail during the learning process you'd almost certainly develop some
negative level of frustration.
Doug Semler - 25 Sep 2007 03:35 GMT
>> > Jon,
>>
[quoted text clipped - 12 lines]
> detail during the learning process you'd almost certainly develop some
> negative level of frustration.

For me, unfortunately (or fortunately??) the words "worry" and "obsess" mean
almost the exact same thing.  Psychological thing I guess...

On the other hand, not understanding the various features and semantics of
the language/environment in which you are programming, whether it be the
nuances of IDisposable or virtual destructors or even whether the modulus
operator result is negative depending upon the sign of the dividend or
divisor can be "dangerous".

Signature

Doug Semler, MCPD
a.a. #705, BAAWA.  EAC Guardian of the Horn of the IPU (pbuhh).
The answer is 42; DNRC o-
Gur Hfrarg unf orpbzr fb shyy bs penc gurfr qnlf, abbar rira
erpbtavmrf fvzcyr guvatf yvxr ebg13 nalzber. Fnq, vfa'g vg?

Brian Gideon - 25 Sep 2007 17:41 GMT
> For me, unfortunately (or fortunately??) the words "worry" and "obsess" mean
> almost the exact same thing.  Psychological thing I guess...
[quoted text clipped - 4 lines]
> operator result is negative depending upon the sign of the dividend or
> divisor can be "dangerous".

It certainly can be dangerous.  That's why I make it a point to obsess
over details during the development of a production quality system.
But, for me anyway, when I learn a new language or technology I like
to just get the general idea of a concept and move on.  I'll come back
later to fill in the gaps.  That way I can move forward without
getting too hung up on a confusing or complex concept.

Threading is a good example of this.  The details can get incredibly
confusing in a hurry.  It's nice to get the general gist of all the
higher level concepts before you really dive down and understand the
specifics.  My hunch is that's how most people like to learn...or may
it's just me :)
Jon Skeet [C# MVP] - 25 Sep 2007 20:25 GMT
> It certainly can be dangerous.  That's why I make it a point to obsess
> over details during the development of a production quality system.
[quoted text clipped - 8 lines]
> specifics.  My hunch is that's how most people like to learn...or may
> it's just me :)

I work the other way round - rather than start off with a great big app
without really knowing how it works, I like to start off with an almost
trivial task but make sure I know as much as possible about how
everything works before I move up to the next stage.

Basically, I like building on really firm foundations. It's definitely
a personal preference though. It's often nice to get a *glimpse* of the
big picture before moving onto the detail, of course - but I really
don't feel comfortable doing too much without decent understanding.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

james - 29 Sep 2007 17:55 GMT
> > I was trying to say that for someone just learning C# they don't need
> > to obsess over finding every IDisposable.
>
> I disagree.  That's like saying that someone just learning C++ doesn't need
> to worry about what the "virtual" keyword on a destructor declaration means.

I never said you shouldn't understand IDisposable or that you
shouldn't use it.  Jon only explained half of the pattern... the fact
that Dispose is called by the Finalizer is important.

-James
Doug Semler - 29 Sep 2007 18:01 GMT
>> > I was trying to say that for someone just learning C# they don't need
>> > to obsess over finding every IDisposable.
[quoted text clipped - 7 lines]
> shouldn't use it.  Jon only explained half of the pattern... the fact
> that Dispose is called by the Finalizer is important.

The fact that Dispose may NOT be called by the Finalizer (if it doesn't
implement the pattern properly) or is called by the Finalizer in a non
deterministic manner is more important.  :)

Signature

Doug Semler, MCPD
a.a. #705, BAAWA.  EAC Guardian of the Horn of the IPU (pbuhh).
The answer is 42; DNRC o-
Gur Hfrarg unf orpbzr fb shyy bs penc gurfr qnlf, abbar rira
erpbtavmrf fvzcyr guvatf yvxr ebg13 nalzber. Fnq, vfa'g vg?

Brian Gideon - 24 Sep 2007 14:42 GMT
> Carl,
>
[quoted text clipped - 15 lines]
>
> -James

Omitting a call to Dispose could be problematic in scenarios where the
object holds onto a resource in a manner that prevents other objects
from acquiring the same resource.  Even though you may be finished
using that resource logically it might not be released until the GC
runs.  If you create another instance that attempts to access the same
resource an exception may be thrown.
Carl Johansson - 28 Sep 2007 15:03 GMT
Here is a practical question. Suppose I have the following code:

   public partial class MyForm : Form
   {
       Font boldFont; //Used throughout MyForm

       public MyForm()
       {
           InitializeComponent();
           boldFont = new Font(myControl.Font, FontStyle.Bold);
       }

       //Other code using boldFont...
   }

Now, at some point boldFont is somehow automatically disposed of by the GC
(which I know very little about)?

I.e. I don't have to worry about whether boldFont is going to be disposed of
or not?

Or, should I implement a "better safe than sorry strategy" and let a
destructor explicitly dispose boldFont?

I do find this topic a bit confusing. It feels like .NET is telling me:
"With me you no longer have to worry about returning resources. I'll take
care of it for you ('Wow' feeling here!), unless I don't know how to... ('I
knew it was too good to be true' feeling here)".

Are there some web documents (or part of a book) that can explain this topic
in an easy to follow way?

Best Regards Carl Johansson
Samuel R. Neff - 28 Sep 2007 16:18 GMT
If you instantiate it and it's IDisposable, then it's your
responsibility to call Dispose.  In your case you're extending Form
which has a protected Dispose implementation already which you should
piggyback on top of.

protcted override void Dispose(bool disposing) {
 super.Dispose(disposing);
 if (disposing) {
   if (boldFont != null) {
     boldFont.Dispose();
   }
 }
}

IDisposable is basically an acknowledgement that the component
developer still needs control over how certain resources are released
and it means application developers can not ignore resource management
entirely.

Sam

------------------------------------------------------------
We're hiring!  B-Line Medical is seeking .NET
Developers for exciting positions in medical product
development in MD/DC.  Work with a variety of technologies
in a relaxed team environment.  See ads on Dice.com.

>Here is a practical question. Suppose I have the following code:
>
[quoted text clipped - 29 lines]
>
>Best Regards Carl Johansson

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.