views:

921

answers:

4

Hi,

In C#/.NET, is there any way to get a notification before the object pointed to by a weak reference is destructed? Basically, I want to allow an object to be collected, but do something right before the object is destroyed, without modifying code to add destructors (since I won't know exactly what types of objects will be sued with my code).

Thanks, Robert

+5  A: 

No there is no way to achieve this functionality.

After a bit of speculation, I don't believe it's possible to implement a feature in the manner you are describing.

Consider that at the point the object held by a WeakReference is collected, there are no more references (hence it's collectable). For an event to have any use to you it would need to provide the object as part of the event. This means that the reference has gone from collectable to not-collectable. There is nothing stopping the handling code from retaking a reference on that object. Hence the object can no longer be considered collectable. The CLR would need to make a second pass on the object to re-ensure it was collectable.

You can see how the second time around the event could not be raised because it would lead to uncollectable objects.

It would be a misuse of naming to claim this event was raised just before an object was collected. Simply because any handler could prevent this from being collected by establishing a new reference to the object. Instead it would have to be "ObjectMaybeAboutToBeCollected". This probably won't give you the behavior you're looking for.

JaredPar
Cool, thanks... can you think of any ways to get similar functionality other than WeakReferences?
Robert Fraser
@Robert, other than form of destructors / dispose I can't think of anything off the top of my head
JaredPar
A: 

Your question doesn't make sense to me. Where is the code that's going to be called supposed to reside? Given that the weak references will be nulled before the referenced object is destroyed, it doesn't make sense for it to be part of the class that referenced the about-to-be destroyed object. And there's already code in the referenced object that's called before the object is destroyed - that's the destructor.

What's the actual design problem you want to solve? There may be a better way.

Mark Bessey
I want to create a system where objects are registered to be serialized to server occasionally. The serialized data will be pushed to the server every few minutes (out of my control), so usually the serialized data for all registered objects is calculated then. However, if a registered object is being destructed, I want to calculate the data right before it dies (and that data will be sent with the next batch to the server).
Robert Fraser
That still seems a little funky. If you're going to be sending the serialized data up to a server periodically, why not just have the object that's responsible for the serialization maintain a (nonweak) reference to the registered objects, and release them once they've been uploaded? Given the unpredictability of the destruction timing, you wouldn't want to depend on it for data integrity, anyway.
Mark Bessey
They need to keep being serialized every so often as long as they're alive/changing. It's Silverlight UI preferences (i.e. column widths, etc.), so as long as the UI elements are still around, their state needs to be saved on the server.
Robert Fraser
+3  A: 

You can't do that. However what you can do is to watch when a GC is approaching ( there are new GC APIs in CLR v3.5Sp1 that allows you to do so, GCNotifications )

mfawzymkh
I guess that's as natural a place as any to update the serialized data. Thanks for the info!
Robert Fraser
A: 

For what you are describing, finalizers would be a way better approach.