У меня многопоточное приложение со многими формами, но мне нужно создать экземпляр некоторых классов и вызвать некоторые элементы инициализации перед созданием форм. Конечно, мне нужно выполнить соответствующий код завершения.Могу ли я гарантировать выполнение пользовательского кода для окончательной доработки ПОСЛЕ уничтожения формы?
Вот упрощенный пример .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
/destructor
с моих форм. Выдается ясно смотрит на finalization
секции Form
блока:
finalization
if Application <> nil then DoneApplication;
И DoneApplication
звонки Application.DestroyComponents
, которые эффективно высвобождает все Application
«S принадлежат формы.
Итак, формы, созданные с помощью Application.CreateForm
, будут уничтожены после любого кода внутри основного блока begin..end
.
То, что я хочу, что после того, как Application.Run
все формы будут уничтожены, так что их OnDestroy
обработчики событий могут видеть Config
объект и внешние функции, определенные в моих библиотек DLL. То же самое, если возникает исключение. Но я также хочу иметь обработку исключений стандартного приложения, если Config.Free
или UnlodDlls
рейз (приложение должно все еще существовать).
Обратите внимание, что:
- Я предпочел бы не использовать
finalization
блок (? Бы это было возможно в .dpr), чтобы сохранить код понятнее и Отладка; - На данный момент я предпочитаю не менять слишком много кода (например, динамически создавать формы)
Я думаю, что самое простое решение явно вызвать Application.DestroyComponents
после Application.Run
. Как вы думаете, есть ли какие-то недостатки? Есть ли более элегантное решение?
Спасибо
Спасибо, я вижу вашу точку зрения. Я хотел бы сделать это изменение как «шаг 2», потому что ему нужно изменить мнение всех членов команды ;-) На данный момент я должен гарантировать, что если кто-то добавит форму «стандартный способ», это будет правильно обработано. Почему не 'Application.DestroyComponents'? Что касается DLL, вы правы, но в «LoadDlls» есть другие структуры, которые я хочу правильно освободить, чтобы уловить некоторые утечки памяти в главном коде. – yankee
Система восстановит память при завершении процесса. Вы не можете течь в этот момент. Вероятно, вы достаточно безопасны для вызова 'DestroyComponents' в этот момент. Я бы сделал это правильно, если бы был вами, но тогда я не знаю, какое влияние у вас есть в вашей команде! –
вы меня убедили ;-) – yankee