我正在运行一个 ISAPI 服务,它运行IdHTTPWebBrokerBridge
(用于作为独立 EXE 调试)以及在 Apache 中运行mod_isapi
(在生产环境中)。
在销毁 web 模块时记录一些内容时,我发现了以下问题:
unit LogFactory;
...
initialization
GlobalLogFactory := TMyLogFactory.Create;
finalization
FreeAndNil(GlobalLogFactory);
end.
-
unit MyWebModuleUnit;
...
uses LogFactory;
procedure TMyWebModule.WebModuleDestroy(Sender: TObject);
begin
Assert(Assigned(GlobalLogFactory)); // <-- failure
GlobalLogFactory.GetLogger('D:\test.txt').LogLine('test'); // <-- Nullpointer Exception
end;
LogFactory.pas
在初始化时创建对象GlobalLogFactory
并在完成时销毁它。
但LogFactory.pas:finalization
被称为 BEFORE TMyWebModule.WebModuleDestroy
,因为它仅包含在本单元中,因此最终确定将以相反的顺序完成。
我怎样才能确保我的GlobalLogFactory
将被正确释放(即 FastMM 不会警告内存泄漏),但同时,我想让所有销毁/终结程序有机会记录一些东西?
一种解决方法是LogFactory.pas
在 DPR 文件中明确包含作为第一个单元。但我不太喜欢这样,因为这个 Log-Unit 应该在许多项目中使用,并且只需将它包含在需要记录某些内容的单元中就可以使用它。将此日志单元放在每个可能希望在未来记录某些内容的 DPR 中是一项巨大的工作,而忘记它可能会给不知道我做了什么/需要什么的开发人员带来问题。