我有一个多线程应用程序,其中包含许多表单,但在创建这些表单之前,我必须实例化一些类并调用一些初始化内容。当然,我也必须执行相应的终止代码。
以下是一个简化的 .dpr 文件示例:
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;
这里的问题在于
finally
块内的代码会在我的窗体的OnDestroy
/ 析构函数
之前执行。这一点可以从Form
单元的finalization
部分清晰地看出来:finalization
if Application <> nil then DoneApplication;
DoneApplication
调用Application.DestroyComponents
,这将有效地释放所有属于Application
的窗体。
因此,使用Application.CreateForm
创建的窗体将在主begin..end
块内的任何代码之后被销毁。
我想要的是,在Application.Run
之后,所有窗体都会被销毁,这样它们的OnDestroy
事件处理程序就可以访问Config
对象和我在dll中定义的外部函数。如果发生异常,也是如此。
但是,如果Config.Free
或UnlodDlls
引发异常,我还希望具有标准应用程序的异常处理(应用程序仍然必须存在)。
请注意:
- 我更喜欢不使用
finalization
块(在.dpr中是否可能?)以保持代码更清晰、更易于调试; - 目前,我不想改变太多的代码(例如动态创建窗体)。
我认为最简单的解决方案是在Application.Run
之后显式调用Application.DestroyComponents
。你觉得有什么缺点吗?还有更优雅的解决方案吗?
谢谢。
DestroyComponents
。如果我是你,我会做得更好,但我不知道你在团队中有多少影响力! - David Heffernan