Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   eigenartiges Verhalten bei Onclose eines Formulars (https://www.delphipraxis.net/213873-eigenartiges-verhalten-bei-onclose-eines-formulars.html)

SusiT 11. Okt 2023 22:29

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

himitsu 11. Okt 2023 22:45

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?

BerndS 12. Okt 2023 06:07

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.

himitsu 12. Okt 2023 07:13

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/...)

fisipjm 12. Okt 2023 07:24

AW: eigenartiges Verhalten bei Onclose eines Formulars
 
Moin,

darf ich da mal einhacken.
Zitat:

Zitat von himitsu (Beitrag 1527995)
...Und bei Forms besser Release....

Ist
Delphi-Quellcode:
Release
nicht als
Delphi-Quellcode:
deprecated
geflagt? Oder ist das nur bei Firemonkey so? Normalerweise setzt man doch im
Delphi-Quellcode:
OnClose
Event der jeweiligen from den OnClose handle auf
Delphi-Quellcode:
caFree
und ruft dann einfach ein
Delphi-Quellcode:
Tform.Close
auf.
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

dummzeuch 12. Okt 2023 07:55

AW: eigenartiges Verhalten bei Onclose eines Formulars
 
Zitat:

Zitat von himitsu (Beitrag 1527995)
Erstens: Man ruft nicht Destroy auf, sondern Free. Und bei Forms besser Release.

Release ist dazu gedacht, um aus einem Event des Formulars aufgerufen zu werden, so dass es erst freigegeben wird, wenn der Event beendet wurde. In allen anderen Situationen sollte man Free aufrufen.


Zitat:

Zitat von himitsu (Beitrag 1527995)
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?

Vermutlich korrekt.

SusiT 12. Okt 2023 08:16

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.

Gausi 12. Okt 2023 08:53

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).

Kas Ob. 12. Okt 2023 09:08

AW: eigenartiges Verhalten bei Onclose eines Formulars
 
Zitat:

Zitat von SusiT (Beitrag 1528003)
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.

So you are not mentioning what the form has for "Action: TCloseAction" in FormClose, yet you releasing it from the MainForm !! :gruebel:

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.

bcvs 12. Okt 2023 10:36

AW: eigenartiges Verhalten bei Onclose eines Formulars
 
Zitat:

Zitat von SusiT (Beitrag 1528003)
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.

Warum so kompliziert? Bei nicht modalen Forms brauchst du überhaupt kein destroy, free oder release.
Einfach nur:
Delphi-Quellcode:
procedure TMyForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;
Falls du die Formvariable noch brauchst, um zu überprüfen, ob die Form existiert, kannst du sie hier auch auf nil setzen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:28 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz