|
Most of the classes in ADO.NET includes a Dispose() method. I know it is called to release unmanaged objects. But when it is called, immediately the objects will be removed or it will remove only the references, and objects will be removed on the next collection cycle ?
|
|
|
|
|
The unmanaged objects are released right away, that's how Dispose always works.
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillionOneHundredAndFortySevenMillionFourHundredAndEightyThreeThousandSixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it )
|
|
|
|
|
Christian Graus wrote: The unmanaged objects are released right away, that's how Dispose always works.
Thanks Christian. But what is the difference between removing reference and removing object ? If reference got removed, how it can identify which was the object in the memory ? So I felt GC will remove both reference and it's object. Right ?
|
|
|
|
|
Dispose cleans up unmanaged resources. It exists apart from GC and from the collection of the object that held the unmanaged resource. The GC will remove the object, as all references have expired. At this point, Finalise is called, which should clean up the same stuff Dispose does, you call Dispose to have stuff cleared without waiting for GC.
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillionOneHundredAndFortySevenMillionFourHundredAndEightyThreeThousandSixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it )
|
|
|
|
|
Christian Graus wrote: The GC will remove the object, as all references have expired.
Ok. So it won't clear the reference alone.?
Christian Graus wrote: At this point, Finalise is called, which should clean up the same stuff Dispose does, you call Dispose to have stuff cleared without waiting for GC.
Ok, So you are telling that even if Dispose() is not called explicitly, GC will call it and dispose the unmanaged code. But AFAIK, GC won't consider the unmanaged resources. That's what they provided Dispose() to call explicitly. What do you think ?
|
|
|
|
|
The standard implementation in objects with unmanaged references is to call Dispose from the destructor. If you forgot to call Dispose it will still be called from the garbage collector when it gets arround to release the object.
This does not mean you shouldn't call Dispose, just like the fact that your car has airbags doesn't mean you should crash it.
I recommend you Google C# dispose pattern[^] and read a bit about how it is implemented (including the use of a destructor).
|
|
|
|
|
lmoelleb wrote: If you forgot to call Dispose it will still be called from the garbage collector when it gets arround to release the object.
See the following from MSDN
MSDN says: Do not assume that Dispose will be called. Unmanaged resources owned by a type should also be released in a Finalize method in the event that Dispose is not called.
And the design pattern says, not to call Dispose() method from Finalize. What do you say ? This makes things in confusion.
|
|
|
|
|
Sorry I wasn't clear enough. With "it" I was referring to "whatever code cleans up the object", not specifically the Dispose method. I can see this was not clear the way I wrote it.
To avoid confusing statements I'll just include the standard dispose pattern here.
From memory, typing streight into the editor - syntax errors to be expected, but the pattern should be more or less correct.
<br />
class Whatever : IDisposable<br />
{<br />
~Whatever<br />
{<br />
Dispose(false); <br />
}<br />
<br />
public void Dispose()<br />
{<br />
Dispose(true);<br />
}<br />
<br />
private void Dispose(bool disposing)<br />
{<br />
if (disposing)<br />
{<br />
<br />
<br />
GC.SuppressFinalize(this)<br />
}<br />
}<br />
}<br />
|
|
|
|
|
Great. So assume I am not writing the Finalizer method for my class. I just wrote only Dispose(). So will GC call the Dispose() method ? What will happen to the object that uses unmanaged references if it is not cleared on Dispose()/Finalize ?
|
|
|
|
|
No, the GC will never call Dispose, hence the need for the finalizer in the first place.
Unmanaged objects that are not released will typically be released by the operating system when the process terminates. A few resource types (for example memory shared between processes) will not be released before next reboot.
|
|
|
|
|
lmoelleb wrote: No, the GC will never call Dispose, hence the need for the finalizer in the first place.
Thanks. I need one more help. Will Finalize method available there for all classes by default ? If Finalize method is not there, What GC will call ?
Is it a good practice to write a Finalize method when class contains Dispose() ? But MSDN say's it's costly in performance.
|
|
|
|
|
1) No, classes do not have a default finalize and if you do not add one nothing will be called.
2) A Finalizer is not needed if you have no unmanaged code to clean up (as you can see in my example, nothing happens in the finalizer if there are no unmanaged references.
3) Yes, a finalizer can impact performance - as I wrote in a comment in my example a finalizer will force the object to be promoted a generation in the garbage collector before it is released (which does not matter if it is a single object you dispose when closing the application, but for something you use a lot it is a problem).
However you will see that the call to Dispose result in a call to GC.SuppressFinalize(this) which basically disable the finalizer for the object once it has been Disposed (as we have cleaned up the references no need to call it again). This elimintes the performance hit when Disposed is used correctly (as you should always be carefull to do with objects implementing IDisposable).
|
|
|
|
|
Thanks for helping. It was really worth information. Thanks again for sharing.
|
|
|
|
|
lmoelleb wrote: Yes, a finalizer can impact performance - as I wrote in a comment in my example a finalizer will force the object to be promoted a generation in the garbage collector before it is released (which does not matter if it is a single object you dispose when closing the application, but for something you use a lot it is a problem).
Adding a finalizer to a class does affect perfromance, but not because it causes the object to change generations. Any classes that implement a finalizer are automatically placed on a separate finalization queue when they are created, even if you do nothing with the object and immediately call Dispose . This queue is checked each time a GC cycle runs.
lmoelleb wrote: However you will see that the call to Dispose result in a call to GC.SuppressFinalize(this) which basically disable the finalizer for the object once it has been Disposed (as we have cleaned up the references no need to call it again). This elimintes the performance hit when Disposed is used correctly (as you should always be carefull to do with objects implementing IDisposable).
Yes, the Dispose method should always include a call to GC.SupressFinalize , but it still doesn't eliminate the performance hit if your class has a finalizer. The purpose here is to prevent finalization from happening a second time unneccesarily.
|
|
|
|
|
N a v a n e e t h wrote: Is it a good practice to write a Finalize method when class contains Dispose() ? But MSDN say's it's costly in performance.
You should generally avoid writing finalizers if at all possible. They are difficult to write properly and do add a performance cost to using your class.
You should take a look at this article[^] for more detailed information regarding Dispose, finalizers, and the Dispose pattern.
|
|
|
|
|
First, please use the <pre> tags for large code blocks like this so it keeps the formatting.
lmoelleb wrote: To avoid confusing statements I'll just include the standard dispose pattern here.
A few points where you have really deviated from the pattern:
Your finalizer should not call Dispose , really under any circumstances. You introduce a lot of extra complexity to your resource cleanup logic by doing this and introduce a much higher chance for failure. Most of the assumptions you can make about the state of the runtime are not valid when running during finalization and most of the classes and methods are not safe to be used during finalization.
The call to GC.SupressFinalize should be in the public Dispose() method, right after the call to Dispose(true) . There are probably two reasons I can give for this. One is that is simply the way the pattern is defined, which isn't an entirely helpfull answer. The other reason is that the Dispose(bool) method should be the one that encapsulates all of the cleanup logic and that this method knows wheter it is being called to do explicit cleanup or being called due to a garbage collection cycle. Because of that, the method really would need to call GC.SupressFinalize under certain conditions only. By moving the call to the public Dispose() method, those risks/concerns are removed. The ordering is still important as it ensures that GC.SupressFinalize only gets called if the Dispose operation completes successfully.
The Dispose(bool) should be protected, not private, to allow any derived classes the ability to override it.
Again, the call to GC.SupressFinalize does tell the GC that it doesn't need to finalize a second time, but this really has nothing to do with generation promotion.
|
|
|
|
|
With regards to calling Dispose(false) from the finalizer, I stole the idea from these guys:
MSDN[^]
Just out of curiosity - who should ever call Dispose(false) if not the finalizer?
Moving GC SuppressFinalize is correct - I was typing from memory and trying to make sure the code did the right thing more than making sure it looked correct. Which was probably a mistake, but still better than making sure it looks correct but doesn't do the right thing. The way my code is written SuppressFinalize could be called multiple time for derived classes (yes, Dispose(bool) should be virtual and protected). It should not break anything but obviously isn't optimal.
With regards to suppress finalize I do agree there is an extra performance hit even when calling SuppressFinalize, and I should have used the term "minimize" performance hit. With regards to promotion, here is one of the sources confirming this (they might be wrong, but I have no reason to doubt them): MSDN Magazine[^]. I have not found any references to the finalizer queue management being a significent performance problem compared to the longer living objects on MSDN, but maybe I just missed it.
|
|
|
|
|
lmoelleb wrote: With regards to calling Dispose(false) from the finalizer, I stole the idea from these guys: MSDN[^]
I see where this could be confusing. The example they are providing is for implementing a base class that also implements a finalizer. In this scenario, you should make the call to Dispose(false from the finalizer of the base class, but the derived classes should not have their own finalizer or public Dispose() method. The derived classes should only override the Dispose(bool disposing) method.
lmoelleb wrote: Just out of curiosity - who should ever call Dispose(false) if not the finalizer?
Off hand, I can't think of anything.
lmoelleb wrote: With regards to promotion, here is one of the sources confirming this (they might be wrong, but I have no reason to doubt them): MSDN Magazine[^].
I am very familiar with this article, and Jeffery Richter is one of the primary people responsible for the GC implementation in .NET. I did find the statement you are referring to where he clearly states:
Finalizable objects get promoted to older generations, which increases memory pressure and prevents the object's memory from being collected when the garbage collector determines the object is garbage. In addition, all objects referred to directly or indirectly by this object get promoted as well.
In that respect, I don't think the finalization queue management is much more significant than longer living objects, but the whole idea behind the GC is that, ideally, you want to have as few long lived objects as possible.
|
|
|
|
|
N a v a n e e t h wrote: But AFAIK, GC won't consider the unmanaged resources. That's what they provided Dispose() to call explicitly. What do you think ?
That is correct. The GC does not know how to release unmanaged resources, which is the reason for using the Dispose pattern. If your class properly implements the pattern, then the resources would get released when the GC runs. The public Dispose method is available to help provide a more deterministic way to release the unmanaged memory.
If you want more details, check out this article[^].
|
|
|
|
|
HI,
i am trying to work with windows form....
Pardon me for asking such a basic question....
1)i have a text box and a combo box and a button in windows form......
when i click on the button i want the item selected in my combobox to displayed in the text box......what is the code for this?? i tried the following code "txtBranch.Text = cmbBranch.SelectedIndex();"
2)similarly if i add a datagrid to this i want the data grid to display this item selected in the combobox......what is the code for this??
3)if anybody can provide any link that will help me to get familiarise in windows controls that will be good....
thanking you
j
|
|
|
|
|
kabutar wrote: i tried the following code "txtBranch.Text = cmbBranch.SelectedIndex();"
Well, that won't work. The reason is that the selected index is a number. Also, it's a property, so the brackets are wrong. You would have got error messages explaining this. Try txtBranch.Text = cmbBranch.Text
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillionOneHundredAndFortySevenMillionFourHundredAndEightyThreeThousandSixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it )
|
|
|
|
|
Hi,
ThankYou it worked.......Thanks a lot......
i tried google to find links that will help me to learn windows forms myself...
but i cannot find anything......
if its not much trouble can you get me a link .....
thanks again
j
|
|
|
|
|
How do i Add new column to the table called as “Nature of Comment" in a existing page,in that there,it has a drop down box.The drops down fields are: Bug, Suggestion, Grammar, and Formatting.thks a lot.
-- modified at 1:55 Wednesday 24th October, 2007
alok2171
|
|
|
|
|
Sounds trivial to impliment. Which bit are you stuck on ?
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillionOneHundredAndFortySevenMillionFourHundredAndEightyThreeThousandSixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it )
|
|
|
|
|
alok2171 wrote: Addition of a new column to the table called as “Nature of Comment",in that there,it has a drop down box.The drops down fields are: Bug, Suggestion, Grammar, and Formatting.thks a lot.
What is your question ?
|
|
|
|