K
Kevin Frey
If you have a class that manages a resource (or something similar such as an
unmanaged pointer), and you implement a Dispose( ) method, are you mandating
to the users of your assembly that they *must* use this method to clean up
(or endure leaks or whatever)? Does this become one of their contractual
obligations in using this assembly?
Are are you simply saying to developers: "Because this class manages a
resource, Dispose( ) gives you the opportunity to force this object to
relinquish its resources at an explicit point." In other words, if the user
*does not* call Dispose( ), then the finaliser should still (at some point)
take care of cleaning up the resources, and it is *legal* for a program to
be written this way?
The reason I ask is that we have a quite complicated framework of Managed
objects (actually written in Managed C++) that control unmanaged resources
(native C++ objects). The key complication is that there are dependencies
amongst the unmanaged resources.
For example, a UEntity unmanaged object requires a USession unmanaged object
in order to communicate with an application server over TCP/IP,. The UEntity
unmanaged object is controlled by a managed Entity object, and the USession
object is controlled by a managed Session object. Naturally enough when
Entity finalises, it will release its corresponding resources, with same
said for the Session object.
The nett result is that, without convoluted handling code, it is entirely
possible for Session to finalise *before* Entity. The finaliser for Session
would in turn clean up USession.
The finaliser for Entity is now stuck between a rock and a hard place. It
needs USession to ensure it can communicate something back to the
application server, yet USession has been destroyed.
Has anyone come across this kind of situation before? It would seem to me
that the only practical way of ensuring that the dependencies are retained
is to use reference-counted pointers for the unmanaged resources.
That way Session holds 1 reference to the USession object, and Entity holds
1 reference. USession only "self-destructs" if the reference count drops to
zero, so a finalise of Session ahead of USession would reduce the reference
count but not result in object destruction of USession because Entity is
still holding a reference.
If anyone has solved this in any other different/lateral/imaginative way I'd
be pleased to hear about it.
Thanks
Kevin
unmanaged pointer), and you implement a Dispose( ) method, are you mandating
to the users of your assembly that they *must* use this method to clean up
(or endure leaks or whatever)? Does this become one of their contractual
obligations in using this assembly?
Are are you simply saying to developers: "Because this class manages a
resource, Dispose( ) gives you the opportunity to force this object to
relinquish its resources at an explicit point." In other words, if the user
*does not* call Dispose( ), then the finaliser should still (at some point)
take care of cleaning up the resources, and it is *legal* for a program to
be written this way?
The reason I ask is that we have a quite complicated framework of Managed
objects (actually written in Managed C++) that control unmanaged resources
(native C++ objects). The key complication is that there are dependencies
amongst the unmanaged resources.
For example, a UEntity unmanaged object requires a USession unmanaged object
in order to communicate with an application server over TCP/IP,. The UEntity
unmanaged object is controlled by a managed Entity object, and the USession
object is controlled by a managed Session object. Naturally enough when
Entity finalises, it will release its corresponding resources, with same
said for the Session object.
The nett result is that, without convoluted handling code, it is entirely
possible for Session to finalise *before* Entity. The finaliser for Session
would in turn clean up USession.
The finaliser for Entity is now stuck between a rock and a hard place. It
needs USession to ensure it can communicate something back to the
application server, yet USession has been destroyed.
Has anyone come across this kind of situation before? It would seem to me
that the only practical way of ensuring that the dependencies are retained
is to use reference-counted pointers for the unmanaged resources.
That way Session holds 1 reference to the USession object, and Entity holds
1 reference. USession only "self-destructs" if the reference count drops to
zero, so a finalise of Session ahead of USession would reduce the reference
count but not result in object destruction of USession because Entity is
still holding a reference.
If anyone has solved this in any other different/lateral/imaginative way I'd
be pleased to hear about it.
Thanks
Kevin