![]() |
eigenartiges Verhalten bei Onclose eines Formulars
Guten Abend.
Mir ist ein eigenartiges Verhalten beim Ablauf des Schließens eines Formulars aufgefallen und mich interessiert ob dieses Verhalten bekannt ist. Der normale Ablauf bei Schließen eines Formulars ist in der Regel folgender: onClose Event wird ausgelöst (Klick auf Kreuz) Formularvariable wird Released -> Event wird erzeugt OnDestroy Prozedur wird aufgerufen In OnDestroy werden alle möglichen Objekte FreeAndNil gesetzt und die Speicherbereinigung findet statt. Ich habe ein sehr komplexes Formular mit sehr viel Inhalt. Jetzt das komische Verhalten: In bestimmten Konstellationen schaffe ich es, dass das Formular schneller schließt als es tatsächlich seinen eigenen Code durchläuft und abarbeitet. Wenn ich während der Abarbeitung einer Prozedur des Formulars das Formular schließe (eine Prozedur die eben mehr Zeit benötigt) , dann wird OnDestroy schneller erreicht und ausgeführt als die Abarbeitung der Prozedur die noch in Arbeit ist. Das hat nen blöden Nebeneffekt. In OnDestroy werden Objekte auf nil gesetzt, die in der noch nicht fertigen Prozedur verwendet werden. Die Folge ist eine Exception mit Zugriffsverletzung und einer ganzen Menge anderer unschöner Fehler. Jetzt frage ich mich, wie kann ich in oder vor Destroy erkennen, dass noch irgendwelcher Code bearbeitet wird? Ähnlich wie bei waitfor im Threading. Dieses parallele Verhalten deutet auch darauf hin, das hier 2 Threads am Laufen sein müssen? Main Thread vom Formular und ein Schließen Thread? Viele Grüße |
AW: eigenartiges Verhalten bei Onclose eines Formulars
Erstens: Man ruft nicht Destroy auf, sondern Free. Und bei Forms besser Release.
Ist die Form Modal, dann nur Close und niemals Destroy/Free oder Dergleichen. Wie viel wollen wir wetten, dass du irgendwo ein Application.ProcessMessages, Application.HandleMessage, ShowMessage oder Dergleichen aufrufst, welches Messages mitten der Behandlung ausführt, anstatt erst anschließend? |
AW: eigenartiges Verhalten bei Onclose eines Formulars
Eine Lösung, um das Close während der Ausführung der Prozedur zu verhindern wäre, das Ereignis TForm.OnCloseQuery zu nutzen und hier CanClose auf false zu setzen, wenn die Prozedure noch nicht fertig ist. Dazu wäre eine Variable hilfreich, die besagt, ob die Prozedure noch aktiv ist.
Ich lasse länger laufende Prozeduren möglichst nie im Hautthread laufen. |
AW: eigenartiges Verhalten bei Onclose eines Formulars
Wenn jemand aber bösartig Free/Destroy aufruft, dann wird OnCloseQuery ignoriert (nicht aufgerufen).
Destroy gibt das Objekt IMMER frei, egal ob jemand noch was abbrechen will (Exception/Abort/...) |
AW: eigenartiges Verhalten bei Onclose eines Formulars
Moin,
darf ich da mal einhacken. Zitat:
Delphi-Quellcode:
nicht als
Release
Delphi-Quellcode:
geflagt? Oder ist das nur bei Firemonkey so? Normalerweise setzt man doch im
deprecated
Delphi-Quellcode:
Event der jeweiligen from den OnClose handle auf
OnClose
Delphi-Quellcode:
und ruft dann einfach ein
caFree
Delphi-Quellcode:
auf.
Tform.Close
Da ich aber an der Stelle auch immer höchst unsicher bin, würd ich das gern nutzen um auch für mich mal Klarheit zu schaffen :-D Grüße und einen guten Start in den Tag PJM |
AW: eigenartiges Verhalten bei Onclose eines Formulars
Zitat:
Zitat:
|
AW: eigenartiges Verhalten bei Onclose eines Formulars
Die Form ist nicht mit ShowModal geöffnet sondern nur mit Show.
Beim schließen der Form wird das onClose Event getriggert -> FormClose in FormClose wird eine callback funktion des parents aufgerufen in welcher form.Release; form := nil; gesetzt wird. Bei Release wird das onDestroy Event getriggert und führt im Formular das geschlossen wird, die Prozedur FormDestroy auf. So ist im Moment der Ablauf bei mir. Danke für dein Wettangebot, allerdings muss ich passen. Ich habe jetzt schon das Gefühl, dass ich diese Wette verlieren würde :-D Ich prüfe dies mal. |
AW: eigenartiges Verhalten bei Onclose eines Formulars
Release ist doch dafür da, dass ein Form "geordnet" freigegeben werden kann, auch in eigenen Event-Handlern. Dann direkt auch die Formvariable zu nilen ist glaube ich keine besonders gute Idee. Das kann gut gehen, muss aber nicht.
Lass das mal weg, und merke dir anderweitig, ob das Formular ggf. später neu erzeugt werden muss oder nicht (also nicht per Test auf =Nil). |
AW: eigenartiges Verhalten bei Onclose eines Formulars
Zitat:
I suggest to use one method to close/release a form, not both at the same time, one method will do the job right, two will burn the meal for sure. |
AW: eigenartiges Verhalten bei Onclose eines Formulars
Zitat:
Einfach nur:
Delphi-Quellcode:
Falls du die Formvariable noch brauchst, um zu überprüfen, ob die Form existiert, kannst du sie hier auch auf nil setzen.
procedure TMyForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin Action := caFree; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:38 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz