.NET Forum / Languages / C# / September 2007
C# compiler option to find classes that implement IDisposable
|
|
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 MagazinesGet 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 ...
|
|
|