Puzzled with Finalizers
-
Hello, I'm puzzled with a simple issue in finalizers. If I have a class containing a reference to an object, isn't it supposed that the referenced object isn't applicable for GC collection except after my object is finalized?
-
Hello, I'm puzzled with a simple issue in finalizers. If I have a class containing a reference to an object, isn't it supposed that the referenced object isn't applicable for GC collection except after my object is finalized?
Not at all. As soon as there are no active references to your object, the reference to the other object is also considered inactive. If the other object doesn't have a Finalizer, it's very likely that it will be garbage collected first. You can't rely on the order that the objects are garbage collected, so you can't use the Finalizer for cleanup. That is what the IDisposable interface is used for.
Despite everything, the person most likely to be fooling you next is yourself.
-
Not at all. As soon as there are no active references to your object, the reference to the other object is also considered inactive. If the other object doesn't have a Finalizer, it's very likely that it will be garbage collected first. You can't rely on the order that the objects are garbage collected, so you can't use the Finalizer for cleanup. That is what the IDisposable interface is used for.
Despite everything, the person most likely to be fooling you next is yourself.
Yes, I read about that, but it doesn't make much sense to me. Regardless, what can I do if I need to enforce an order for finalizers? Both objects have critical finalizers, but one of them must run before the other; otherwise an access violation occurs... Thanks for your help
-
Yes, I read about that, but it doesn't make much sense to me. Regardless, what can I do if I need to enforce an order for finalizers? Both objects have critical finalizers, but one of them must run before the other; otherwise an access violation occurs... Thanks for your help
C# uses non-deterministic finalisation. The dispose pattern is c#'s way of simulating a deterministic destructor. Implement the dispose pattern, put your release code inside the
if(isDisposing)
block. Then make sure you call .Dispose in the correct order. (Or make one object call dispose on the object it contains). http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx[^] http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx[^]Simon
-
C# uses non-deterministic finalisation. The dispose pattern is c#'s way of simulating a deterministic destructor. Implement the dispose pattern, put your release code inside the
if(isDisposing)
block. Then make sure you call .Dispose in the correct order. (Or make one object call dispose on the object it contains). http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx[^] http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx[^]Simon
Thanks for your help. I read a lot about the Disposable pattern, and I implement it (according to the Disposable Design Principle[^]). However, I'm writing a library, so I don't actually control the order of calling Dispose methods. I tried to encapsulate it, but then I ran into referencing objects in the finalizer... Another issue is when the application is rudely unloaded; my (critical) finalizers must run in the correct order, or else the (external) library I'm using would cause an access violation. I thought about having all the finalization logic in one class, but I had to maintain a list of delegates to be called during finalization. Now this list is again a managed object, so I shouldn't be referring to it! I'm confused! :confused: Thanks again.
-
Thanks for your help. I read a lot about the Disposable pattern, and I implement it (according to the Disposable Design Principle[^]). However, I'm writing a library, so I don't actually control the order of calling Dispose methods. I tried to encapsulate it, but then I ran into referencing objects in the finalizer... Another issue is when the application is rudely unloaded; my (critical) finalizers must run in the correct order, or else the (external) library I'm using would cause an access violation. I thought about having all the finalization logic in one class, but I had to maintain a list of delegates to be called during finalization. Now this list is again a managed object, so I shouldn't be referring to it! I'm confused! :confused: Thanks again.
Your only chance is to use the
Dispose pattern
and propagate it down your object graph(s), and additionally usetry/catch
logic in the appropriate places. Finalizers for sure will lead you nowhere since - as stated above - they are indeterministic in order. The logic may become complicated depending on what you are doing - but there has to be one.HosamAly wrote:
Another issue is when the application is rudely unloaded;
If that means 'crash' or 'cancelling the app via task manager' there's exactly nothing you can do. (Anyway, this is exceptional and not part of a programs normal behaviour, so you're not really to blame for things that happen in this case.) Regards Thomas
www.thomas-weller.de Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.
Programmer - an organism that turns coffee into software.