Delphi: что делать, если форма не может освободиться при выходе из приложения - PullRequest
1 голос
/ 04 сентября 2010

Я использую Delphi (7-2010) и пытаюсь найти хороший способ обработки исключений при освобождении форм приложения.Приложение имеет несколько форм, которые принадлежат объекту Application.Когда пользователь выходит из системы, мне нужно освободить все существующие формы, чтобы не поддерживать состояние пользователя, а затем показать диалоговое окно входа для следующего пользователя, который входит в систему.

Иногда при попытке освобождения возникает исключение.одна из форм.Это оставляет форму в памяти, но в неизвестном / непригодном для использования состоянии, поэтому я не могу повторно использовать форму для следующего пользователя, а также не могу избавиться от нее из памяти.Поскольку формы принадлежат приложению, я не могу напрямую создать новую версию формы для следующего пользователя, так как это приведет к ошибке «Компонент с именем MyForm уже существует» из VCL, и я немного не уверенв любом случае иметь старые экземпляры формы в памяти.

Я бы хотел посмотреть, что другие будут делать в этом случае.Вот несколько идей:

  • Завершите работу приложения, когда получите эти исключения, поэтому обязательно протрите планшет.В любом случае, пользователь выходит из системы, поэтому, скорее всего, он завершил работу с приложением.При необходимости перезапустите приложение.
  • Сделайте формы, не принадлежащие Приложению, чтобы вы могли создавать их несколько экземпляров и удостовериться, что все несвободные / поврежденные формы как минимум скрыты.
  • Динамически генерируйте имя каждой формы или устанавливайте его пустым, чтобы никогда не было повторяющихся имен и ошибок «уже существует» из VCL.
  • Пишите приложение так хорошо, чтобы никогда не было исключенийпри освобождении объектов (нереально - мне нужен план на случай непредвиденных ошибок).


Мое решение было одной из первоначальных идей выше.Я добавил блок try / exception вокруг цикла, который освобождает формы, и, если возникает исключение, я показываю сообщение об ошибке пользователю, не вызывая его, а затем вызываю ExitProcess (0), чтобы немедленно убить приложение.

Ответы [ 2 ]

6 голосов
/ 04 сентября 2010

На самом деле нет хорошего способа обработки исключений, возникающих внутри деструктора.И я бы не назвал это «нереальным», чтобы ожидать, что они никогда не будут подняты, поскольку деструктор не должен делать ничего, что может вызвать исключение.Если вы делаете что-либо, кроме освобождения памяти или другой очистки (освобождение дескрипторов, закрытие соединений и т. Д.), Вы почти наверняка делаете что-то не так.

Что вызывает исключения, кстати?Вы в состоянии воспроизвести ошибку последовательно?Ваш лучший способ действий - просто исправить ошибки.Их не должно быть слишком много.

4 голосов
/ 04 сентября 2010

Чаще всего ошибки возникают при уничтожении форм, потому что все еще есть какой-то обработчик событий, выполняющий и ссылающийся на уже уничтоженный объект. Вот почему TForm.Release был создан для использования вместо TForm.Free в таких случаях.

Из справки:
Используйте Release, чтобы уничтожить форму и освободить связанную с ней память. Release не разрушает форму, пока все обработчики событий формы и обработчики событий компонентов в форме не завершат выполнение. Release также гарантирует, что все сообщения в очереди событий формы будут обработаны до того, как форма будет освобождена. Любые обработчики событий для формы или ее дочерних элементов должны использовать Release вместо Free (Delphi) или delete (C ++). Невыполнение этого требования может привести к ошибке доступа к памяти.

...