.NET Forum / .NET Framework / New Users / March 2006
How critical is it to call Dispose()
|
|
Thread rating:  |
chak - 27 Feb 2006 13:18 GMT How critical is it to call Dispose() of a class which implements IDisposable(). Though it may be recommended as a good practise, which situations make it very important ?
Regards,
Chak.
Kevin Spencer - 27 Feb 2006 13:46 GMT It's very important if you app allocates a lot of memory in a short amount of time, and if you use a lot of the type of class you don't want to Dispose for some reason. It's also important if you're not sure the class implements Dispose correctly. Microsoft implements it correctly, but not everyone else does.
It's always a good idea to call it.
 Signature HTH,
Kevin Spencer Microsoft MVP .Net Developer A brute awe as you, a Metallic hag entity, eat us.
> How critical is it to call Dispose() of a class which implements > IDisposable(). Though it may be recommended as a good practise, which [quoted text clipped - 3 lines] > > Chak. news.microsoft.com - 27 Feb 2006 14:04 GMT if you know your not going to use the object you can call it...
www.gusse.net
> How critical is it to call Dispose() of a class which implements > IDisposable(). Though it may be recommended as a good practise, which [quoted text clipped - 3 lines] > > Chak. Nick Hounsome - 27 Feb 2006 14:08 GMT > How critical is it to call Dispose() of a class which implements > IDisposable(). Though it may be recommended as a good practise, which > situations make it very important ? If you don't call Dispose() (or use the using statement) then you MAY run out of resources or prevent others from accessing files or pretty well anything else depending on the object.
IF your object becomes garbage and IF/WHEN the GC collects it it will call the Finalize method which should release the resources anyway.
If you retain a reference to the object (and it's easy to do so by accident) then the files opr whatever will never be released.
If you don't retain a reference there is no gaurantee when or even if the GC will run. Usually you will probably get away with it but it would be totally unacceptable in a commercial library.
Cowboy (Gregory A. Beamer) - MVP - 27 Feb 2006 14:11 GMT If you attach to any unmanaged resources, it is critical. This includes those down in the call stack that you did not call yourself (i.e., those that are called by the .NET Framework components). Unless you are going to do a full stack walk and ensure there are no components lower down the stack, I would call Dispose() 100% of the time.
 Signature Gregory A. Beamer MVP; MCP: +I, SE, SD, DBA
*************************** Think Outside the Box! ***************************
> How critical is it to call Dispose() of a class which implements > IDisposable(). Though it may be recommended as a good practise, which [quoted text clipped - 3 lines] > > Chak. AMercer - 27 Feb 2006 14:50 GMT > How critical is it to call Dispose() of a class which implements > IDisposable(). Though it may be recommended as a good practise, which > situations make it very important ? 1. It is playing by the rules, so you should do it. Failing to dispose may work today but fail tomorrow after a .net upgrade without any changes to your code. Honor your oop contracts and genuflect often and peace shall be upon you.
2. Some (fxcop, purists) say always dispose your IDisposables. Hmmm. There are classes that implement IDisposable that also provide a documented alternative. For example, WebResponse provides the Close method, so I Close and I do not Dispose just like the MS provided samples and documentation indicate. That seems reasonable provided you don't go overboard with contract waivers.
3. I go overboard. My general approach to .net development is to follow the examples and add dispose when I get into trouble. I detest the concept and implementation of IDisposable. I feel better now.
4. Dispose is least important at app shutdown. When I shut down my apps, I don't worry about disposing unless I know about an open file or something like that.
5. Dispose is most important when you instantiate-destroy repeatedly and dispose is actually necessary to prevent a memory leak. For example, System.Windows.Forms.MainMenu will leak if you instantiate MainMenu repeatedly and fail to dispose. Sorry, I don't have a list of classes that have this behavior. Even if I did, it may be valid today and not valid tomorrow, so you should always dispose (or equivalent) your IDisposables. Amen.
Michael.Suarez@gmail.com - 02 Mar 2006 17:05 GMT So lets say I have
public int myMethod() { int myInt = 0; string myString = new string(); SqlCommand cmd = new SqlCommand(); MyClass myVar = new MyClass();
//some code
return 0; }
By saying that you should always call Dispose, wouldn't that mean you should have: myInt.Dispose(); myString.Dispose(); cmd.Dispose(); myVar.Dispose();
between //some code and the return statement?
i mean an int takes up so little space, so this might be overkill... but where do you draw the line?
Bruno Jouhier - 02 Mar 2006 20:32 GMT You should read the basic docs on Dispose() first.
Dispose() only exists in classes that implement the IDisposable interface. Usually, these classes are classes that reference directly or indirectly unmanaged resources. Also, the intent of Dispose is *not* to free managed memory (the GC does it, and there is no other way), it is to free the unmanaged resources in a deterministic way.
Then:
> myInt.Dispose(); // nonsense: does not compile, System.Int32 does not > implement IDisposable > myString.Dispose(); // idem > cmd.Dispose(); // YES, SqlCommand implements IDisposable. > myVar.Dispose(); // Only if MyClass implements IDisposable. And the preferred way to write myMethod() is:
public int myMethod() { int myInt = 0; string myString = "some string"; // new string(); does not compile! using (SqlCommand cmd = new SqlCommand()) { MyClass myVar = new MyClass(); //some code } return 0; }
Bruno
> So lets say I have > [quoted text clipped - 21 lines] > i mean an int takes up so little space, so this might be overkill... > but where do you draw the line? Michael.Suarez@gmail.com - 06 Mar 2006 15:41 GMT So SqlCommand, DataSet, DataTable, DataAdapter all implement IDisposable.
Let's say I have a function that uses an object for each one of these classes, and all 4 of the objects are created & instantiated within the function, and no longer needed once the function returns what it needs to return. If I don't dispose of them myself, the GC will eventually get rid of them. If I do dispose of them (either via the using statement, or calls to Dispose()), then that's a few (not a lot, but at least 4) extra lines of code. So is it recommended for me to dispose of all 4 objects myself? or is it overkill? at what point does it become overkill to just dispose of every object you use?
Bruno Jouhier - 11 Mar 2006 15:22 GMT > So SqlCommand, DataSet, DataTable, DataAdapter all implement > IDisposable. [quoted text clipped - 5 lines] > If I don't dispose of them myself, the GC will eventually get rid of > them. Yes, but you cannot predict when (unless you call GC.Collect() yourself, which is not recommended).
Also, this is more costly because the objects have to go through the finalizer queue of the GC. If you dispose them explicitly, their finalization is inhibited and the GC performs better.
> If I do dispose of them (either via the using statement, or calls to > Dispose()), then that's a few (not a lot, but at least 4) extra lines > of code. With the "using" construct, that's very little extra code. If you allocate several resources in a row, you can even group the using clauses and create a single bloc:
using (Resource1 res1 = CreateResource1()) using (Resource2 res2 = CreateResource2()) using (Resource3 res3 = CreateResource3()) { // do something useful }
> So is it recommended for me to dispose of all 4 objects myself? or is > it overkill? at what point does it become overkill to just dispose of > every object you use? No, this is not overkill, this is strongly recommended.
On the other hand, you should not introduce IDisposable interfaces and finalizers everywhere (which is what many people seem to think when they see this feature). You only need to worry about IDisposable and finalizers if the class references UNMANAGED resources.
Michael.Suarez@gmail.com - 14 Mar 2006 20:25 GMT Thank you very much for taking the time to explain it. I like the tip about having several usings and a single block... much cleaner than having several usings with several sets of {}'s and your code tabbed all the way over to the right side of the screen. Definately a very useful tip. Thanks.
The main points I should take away (if i understand you correctly). -if it implements IDisposable, and I am done with it, call dispose (or use using). always. -if i have my own class, only make it implement IDisposable if it is going to access unmanaged resources.
Bruno Jouhier - 15 Mar 2006 20:28 GMT > -if i have my own class, only make it implement IDisposable if it is > going to access unmanaged resources. If what you mean by "going to access unmanaged resources" is "references unmanaged resources through one of its fields", yes. But if the class accesses unmanaged resources temporarily and does not keep references to them, there is no need to make it implement IDisposable.
Bruno
Bruno Jouhier - 28 Feb 2006 08:02 GMT Two potential problems (at least) if you don't call Dispose:
1) you may exhaust unmanaged resources (memory, handles, etc.) because the GC does not know about these resources. So, if it does not run quickly enough, you run into problems. Also, you put more load on the GC because the IDisposable objects go through the finalizer queue in this case (Dispose, if correctly implemented, removes them from the finalizer queue).
2) you lock unmanaged resources for an unpredictable amount of time. For example, if you don't Dispose a Stream on an open file, the file remains open and you won't be able to open it again until the GC collects the Stream. Sometimes you will be lucky and your program will work ok, but sometimes the second open will fail.
Morale: follow the guidelines and call Dispose (or better, use the "using" construct if you are in C#).
Bruno
> How critical is it to call Dispose() of a class which implements > IDisposable(). Though it may be recommended as a good practise, which [quoted text clipped - 3 lines] > > Chak. tamberg - 28 Feb 2006 09:51 GMT There is an insightful discussion of IDisposable in Brad Abrams book "Framework Design Guidelines"
http://www.amazon.com/gp/product/0321246756/103-2286131-0889457?v=glance&n=283155 http://blogs.msdn.com/brada/archive/category/2656.aspx
Jeff Louie - 03 Mar 2006 05:58 GMT I would argue that you should not rely on calling Dispose at all, but use the using construct which is exception safe.
Regards, Jeff
Kevin Spencer - 03 Mar 2006 11:52 GMT >I would argue that you should not rely on calling Dispose at all, but > use the > using construct which is exception safe. This is a useful practice, but not always. There are times when the lifetime of a disposable object extends far beyond what is useful (or even possible) to put into a using block.
A using block is simply a convenience for making sure that Dispose is called. It is not a substitute for being aware that Disposable instances should always be disposed.
 Signature HTH,
Kevin Spencer Microsoft MVP .Net Developer A brute awe as you, a Metallic hag entity, eat us.
>I would argue that you should not rely on calling Dispose at all, but > use the [quoted text clipped - 4 lines] > > *** Sent via Developersdex http://www.developersdex.com ***
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 ...
|
|
|