Can I guarrantee execution of custom finalization code AFTER form
destruction?
I have a multithreaded application with many forms, but I have to
instantiate some classes and call some initialization stuff before the
creation of the forms. Of course I have to execute the corresponding
finalization code.
Here is a simplified example of .dpr file:
begin // .dpr project file
LoadDlls;
try
Config := TConfig.Create;
try
Application.Initialize;
Application.Title := 'Foo';
Application.CreateForm(TMainForm, MainForm);
Application.CreateForm(TOtherForm, OtherForm);
//...other forms...
Application.Run;
finally
Config.Free;
end;
finally
UnloadDlls;
end;
end;
The problem here is that the code inside finally blocks get executed
BEFORE the OnDestroy / destructors of my forms. This turns clear looking
at the finalization section of Form unit:
finalization
if Application <> nil then DoneApplication;
And DoneApplication calls Application.DestroyComponents which effectively
Frees all Application's owned Forms.
So, Forms created with Application.CreateForm will be destroyed after any
code inside the main begin..end block.
What I want is that after Application.Run all the forms are destroyed, so
that their OnDestroy event handlers can see the Config object and the
external functions defined in my dlls. Ditto if an exception is raised.
But I also want to have the standard Application's exception handling if
Config.Free or UnlodDlls raise (Application must still exist).
Note that:
I'd prefer not to use a finalization block (would it be possible in .dpr?)
to keep code clearer and debuggable;
For now, I prefer not to change too much code (e.g. dynamically create forms)
I think the simplest solution is to explicitly call
Application.DestroyComponents after Application.Run. Do you think is there
any drawbacks? Is there a more elegant solution?
Thank you
No comments:
Post a Comment