Peter said:
In general, can a class instance destroy itself via one of it's own methods?
Firing an event is like calling a method or function. So the event
handler is called from the object itself, which is still alive at that
time, and therefore it is potentially dangerous to delete it. It's OK to
delete if you are sure that the method where the event is fired from no
longer refers to any of the member variables (or internal resources).
But wait a minute, is it possible at all in .NET to delete an instance?
There is no such thing as a destructor in CLI. You can't force the
deletion of allocated objects, and the garbage collector will only
delete the object once it's not reference by anywhere else. As long as
the object is still alive, it's not going to be garbage collected.
When you Dispose an object, you only destroy its underlying handle. For
example, if it's a file object, Dipose will close the file. If it's a
Graphics object, the device context is released. But the object itself
is still alive after calling Dispose, as far as its member variables go.
Its underlying resource or unmanaged implementation is dead, though,
after a Dispose. In the new C++/CLI syntax you no longer call Dispose,
but use the delete operator instead. The delete operator performs just a
call to Dipose, if I understand it correctly. It's still the garbage
collector that removes the object from the memory.
Whether it's safe to call "delete timer1" from timer1's event handler, I
can't tell for sure, but it might be. It depends how safe its internal
implementation is.
Here's an example where it's not safe to call delete from an event handler:
ref class Unsafe
{
public:
Unsafe()
: unmanaged(new Unmanaged)
{
}
~Unsafe()
{
delete unmanaged;
}
delegate void NotifyEvent(Unsafe^ sender);
event NotifyEvent OnNotify;
void FireNotify()
{
OnNotify(this);
unmanaged->DoSomething(); // booooom!!!!!!
}
private:
Unmanaged* unmanaged;
};
If you call "delete sender" from OnNotify's handler, FireNotify will
crash, because parts of the class's internal implementation is already
dead, and the class doesn't even have protection built in against that.
Also note that an event can have multiple handlers. If you do have
multiple handlers, it can't be guaranteed that a specific handler is the
last one to be called. If you dispose the sender from the handler, other
handlers may still want to access the object. Once again, it's sometimes
possible to make such a class that's safe to be disposed from a handler,
but generally speaking such safety can not always be guaranteed. Without
knowing the implementation, you can never be sure, in my opinion.
Tom