Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Erstellung und Freigabe von Formularen in einem Thread (https://www.delphipraxis.net/182584-erstellung-und-freigabe-von-formularen-einem-thread.html)

Alex_ITA01 3. Nov 2014 10:51

Erstellung und Freigabe von Formularen in einem Thread
 
Hallo zusammen,
ich habe folgendes Problem:

Ein von mir erstellter Thread, initialisiert im Create vom Thread eine Instanz auf ein Objekt (=class).
Dieses Objekt hat im Create wiederrum ein Formular, welches erstellt wird mit AOwner = Nil.
Wenn der Thread beendet wird (=Destroy), wird die Instanz auf das Objekt auch freigegeben. Dieses hat wiederrum im Destroy die Freigabe des Formulars stehen, da es ja mit AOwner=Nil erzeugt wurde.

Der Thread hat FreeOnTerminate = False

Wenn ich oben besagtes durchlaufe, bekomme ich bei der Freigabe des Formulars die Exception: Systemfehler 5:Zugriff verweigert.
Habt ihr eine Idee, woran das liegen kann? Wenn ich das Formular mit AOwner=Application erstelle und es nicht selber freigebe, dann bekomme ich keine Exception.
Im OnDestroy des Formulars steht übrigens kein Quelltext, da auch im OnCreate nichts extra initialisiert wird.

Viele Grüße

Sir Rufo 3. Nov 2014 11:01

AW: Erstellung und Freigabe von Formularen in einem Thread
 
Sorge einfach dafür, dass die Erzeugung und Freigabe im Kontext vom
Delphi-Quellcode:
MainThread
erfolgt.

Grundsätzlich ist es natürlich generell fraglich, wofür das insgesamt gut sein soll. Wenn ich etwas anzeigen möchte, dann erzeuge ich eine Form und sage der zeig mir das da mal an.

Sieht mir eher nach einer Vermischung von Logik und Anzeige aus.

Alex_ITA01 3. Nov 2014 11:12

AW: Erstellung und Freigabe von Formularen in einem Thread
 
Naja, es ist eine Form, die zu dem Thread "gehört" und auch nur dann erzeugt werden soll, wenn es den Thread gibt bzw. dieser erstellt wurde. Er soll sozusagen der "Owner" für das Form sein und hat auch seine entsprechenden Semaphoren und VCL Zugriffe auf die Form...

mkinzler 3. Nov 2014 11:19

AW: Erstellung und Freigabe von Formularen in einem Thread
 
Da die VCL nicht threadsicher ist sollten alle Formulare im Hauptthread erzeugt, manipuliert und freigegeben werden!

himitsu 3. Nov 2014 11:41

AW: Erstellung und Freigabe von Formularen in einem Thread
 
Zitat:

Zitat von mkinzler (Beitrag 1278491)
Da die VCL nicht threadsicher ist sollten alle Formulare im Hauptthread erzeugt, manipuliert und freigegeben werden!

Es werden globale Objekte (Font, Brush, Pen uws.) als Vorlagen verwendet und außerdem registrieren sich die VCL-Forms/Komponenten in globalen Listen.

Man kann Formulare in Threads erzeugen, aber dafür braucht man dann im Thread eine Messagebehandlung und kann die VCL nicht benutzen. (maximal vielleicht eine eigständige VCL, z.B. in einer DLL, wobei die DLL dann auch im Thread geladen/freigegeben werden müsste)

Dejan Vu 3. Nov 2014 12:18

AW: Erstellung und Freigabe von Formularen in einem Thread
 
Zitat:

Zitat von Alex_ITA01 (Beitrag 1278485)
Naja, es ist eine Form, die zu dem Thread "gehört" und auch nur dann erzeugt werden soll, wenn es den Thread gibt bzw. dieser erstellt wurde. Er soll sozusagen der "Owner" für das Form sein und hat auch seine entsprechenden Semaphoren und VCL Zugriffe auf die Form...

Form = GUI
Thread = Logik

Da man das -siehe Sir Rufo- nicht mischen soll, liegt hier ein Designproblem vor. Aber es ist schon klar, was Du bezwecken willst.

Führe dazu eine Klasse ein, die sowohl den Thread startet als auch das Formular sichtbar macht. Nennen wir die mal 'ThreadController'. Der Thread teilt dem ThreadController mit,
  • wenn er gestartet wird => Form sichtbar machen
  • wenn er beendet wird => Form unsichtbar machen
  • wenn es etwas darzustellen gibt => Darstellen
Der Thread kann das über Synchronize-Aufrufe so steuern, das sich alles schön im Kontext des Mainthreads ausgeführt wird. Wenn der Thread das dann auch noch über Events löst, hast Du Form und Thread komplett entkoppelt, d.h. der Thread kennt die Form nicht, meldet aber per Event Änderungen an seinem inneren Zustand. Und der ThreadController sorgt dafür, das diese Änderungen in der Form landen.

Der Thread kann bzw. sollte nach außen hin komplett unsichtbar sein, d.h. Alles läuft über den ThreadController.

himitsu 3. Nov 2014 12:25

AW: Erstellung und Freigabe von Formularen in einem Thread
 
Zitat:

Zitat von Dejan Vu (Beitrag 1278506)
Zitat:

Zitat von Alex_ITA01 (Beitrag 1278485)
Naja, es ist eine Form, die zu dem Thread "gehört" und auch nur dann erzeugt werden soll, wenn es den Thread gibt bzw. dieser erstellt wurde.

Form = GUI
Thread = Logik

Logisch ja, aber praktisch nein.

Ein "Window" (Form/Komponenten), welches per CreateWindow erstellt wird, wird mit dem Thread verbunden, in welchem es erstellt wurde.
Messages landen dann in diesem Thread und werden über dessen Nachrichtenbehandlung verarbeitet.

Darum landen bei der VCL auch PostMesssage, SendMessage und sonstige Events immer im Hauptthread.

Auf Seiten der Messages ist die VCL also threadsave, genauso, als wenn man es manuell über Synchronize machen würde.

Alex_ITA01 3. Nov 2014 12:36

AW: Erstellung und Freigabe von Formularen in einem Thread
 
Ok danke erstmal.
Die Aufrufe zum Form erfolgen auch komplett über Synchronize oder Events. Also entkoppelt ist es sowieso. Wollte aber das Form nicht immer erzeugen wollen im Hauptfenster, da ich den Thread evtl. bei dem einen Projekt benutze (also Form wird gebraucht) und in einem Projekt den Thread nicht drinne habe (Form wird also nicht gebraucht). Deswegen wollte ich dem Thread das Formular erzeugen und freigeben lassen, weil dieser ja weiß, wann werde ich benötigt und wann nicht.

Hat es denn irgendwelche Nachteile, wenn ich als AOwner=Application angebe und die manuelle Freigabe des Formulars bei mir rausnehme?

Viele Grüße

Medium 3. Nov 2014 13:01

AW: Erstellung und Freigabe von Formularen in einem Thread
 
Es ist grundsätzlich nicht zu empfehlen das TForm der VCL in einem Thread zu nutzen, auch wenn es in dessen Kontext geschieht. Die VCL betreibt einfach zu viel non-thread-safe Gelumpe im Hintergrund. Du könntest aber durchaus mit der nackten WinAPI Fenster in einem Thread erzeugen, müsstest dann aber halt auch alles zu Fuß erledigen. Inklusive Nachrichtenschleife usw.
Was du da jetzt machst, ist eine ziemliche Verrenkung zwischen Haupt-(VCL-)Thread und einem anderen. Das wird vermutlich immer irgendwo knallen. Ich würde da eher dem Hauptthread signalisieren ein entsprechendes Fenster bei Bedarf zu erzeugen, und auch Werte die aus dem Thread stammen mittels Messages über den Hauptthread dort anzeigen - nicht mit dieser Synchronize-Krücke.
Ich würde deinen bisherigen Ansatz nicht weiter versuchen hinzufuckeln, das ist imho verschwendete Zeit.

Dejan Vu 3. Nov 2014 13:09

AW: Erstellung und Freigabe von Formularen in einem Thread
 
Zitat:

Zitat von himitsu (Beitrag 1278509)
Zitat:

Zitat von Dejan Vu (Beitrag 1278506)
Form = GUI
Thread = Logik

Logisch ja, aber praktisch nein.

Praktisch auch JA. Denn es geht nicht um irgendeinen Thread, sondern um den ganz konkreten Thread des TE. Und der hat nun gar nichts mit der VCL am Hut. Sollte er mindestens.

Nur weil zufällig die VCL in einem Thread läuft, weil ja alles in einem Thread läuft, sollte man die Grundaussage der Trennung noch nicht mal im Ansatz in Frage stellen ('praktisch: Nein'). Das verwirrt doch nur unnötig.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:59 Uhr.

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