Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi VCL Zugriffe in Multithread Anwendung absichern (https://www.delphipraxis.net/130497-vcl-zugriffe-multithread-anwendung-absichern.html)

QuickAndDirty 9. Mär 2009 14:56


VCL Zugriffe in Multithread Anwendung absichern
 
Hallo,
Ich möchte gerne VCL Zugriffe in einer Multithread Anwendung im Nachhinein
absichern.

Konkret hatten wir bereits öfter das Problem "Leinwand erlaubt kein Zeichnen", das war in der Regel auf nicht threadsichere Laufbalken zurrückzuführen...diese haben wir gegen threadsichere Laufbalken ausgetauscht,
seit dem haben wir das Problem "Leinwand Erlaubt kein Zeichnen" nur noch höchst selten...
Nun ist es mir heute beim laden der DFM Ressource eine Formulars wieder passiert...
...kann ich sowas absichern in dem ich eine Critical Section drumherum mache?
...gibt es nicht noch etwas weniger brutales?

Mir geht es um Formulare die unsichtbar bleiben und nur wegen irgendwelcher Funktionen der
Formulare erzeugt werden. Man muss/soll sie gar nicht sehen , von daher ist "Leinwand erlaubt kein Zeichnen"
besonders ärgerlich.

Was würdet ihr mir raten?
Daten und View trennen ist eher ein Langzeitziel, weil es etliche Formulare sind die so verwendet werden.

OldGrumpy 9. Mär 2009 15:07

Re: VCL Zugriffe in Multithread Anwendung absichern
 
Auch wenns mühsam ist, wirst Du Dich da wohl durchbeissen müssen. Ich habe immer wieder Projekte ähnlicher "Güte", z.B. 500K Zeilen Code und alles wie Kraut und Rüben durcheinander. Da hilft nur entweder neu schreiben oder modular auslagern (Wenn ständig eine Produktivversion verfügbar sein muss, wird letzteres vermutlich vorzuziehen sein)

Luckie 9. Mär 2009 15:10

Re: VCL Zugriffe in Multithread Anwendung absichern
 
Also wenn du die VCL Thread-Klasse verwendest, dann solltest du die Threads mit der Methode Synchronize mit dem Hauptthread synchronisieren.

QuickAndDirty 9. Mär 2009 15:23

Re: VCL Zugriffe in Multithread Anwendung absichern
 
Also , ich erzeuge in dem Thread ein Formular, das eigentlich bereits geblockt ist, d.h. für die zeit pausieren
eh alle anderen Threads in einer While schleife.
Und es wäre Sinnvoll vor dem erzeugen des Formulars Syncronize anzuwenden?

Aus dem Hauptthread heraus?
Ich lese es mir mal durch.

ChrisE 9. Mär 2009 15:26

Re: VCL Zugriffe in Multithread Anwendung absichern
 
Hallo QuickAndDirty,

Ich denke mal, dass du in Deinen Threads Methoden der unsichtbaren Formulare direkt aufrufst. Diese sorgen sowohl für die Datenverarbeitung als auch für die grafische Darstellung. Ich denke, dass du wie du richtig schreibst die Trennung von GUI und Daten brauchst. Aber auch die Daten müssen eigentlich geschützt werden vor multiblen Zugriffen. ThreadA schreib währen ThreadB liest. Diese Gleichzeitigkeit kommt ja auch noch hinzu.

"Leinwand erlaubt kein Zeichnen" kenne ich z.B. auch im Zusammenhang mit ActiveControl. Eine Komponente die Disabled ist und dann ActiveControl werden soll. Meist ist dann die Logig für aktivieren und deaktivieren der Komponenten in den OnShow-Ereignissen der Formulare die ja aber eben nie ausgelöst werden :-(
Naja, ich denke du verstehst was ich meine.

Ich denke meine Vorredner haben bereits schon das wichtigste gesagt:
Syncronize bei den VCL-Threads und die Trennung GUI/Daten muss her :-)

Viel Erfolg.

Chris

[EDIT]Roter Kasten: Die Methoden die du aufrufst kannst du mit Sycronize aufrufen wenn die fragliche Methode keine Parameter hat -> Syncronize(MeineMethode)[/EDIT]

Assertor 9. Mär 2009 15:32

Re: VCL Zugriffe in Multithread Anwendung absichern
 
Hi QuickAndDirty,

Zitat:

Zitat von QuickAndDirty
Also , ich erzeuge in dem Thread ein Formular, das eigentlich bereits geblockt ist, d.h. für die zeit pausieren
eh alle anderen Threads in einer While schleife.
Und es wäre Sinnvoll vor dem erzeugen des Formulars Syncronize anzuwenden?

Aus dem Hauptthread heraus?

Da stimmt dann aber schon einiges nicht. Du solltest das Design überdenken. Prinzipiell GUI und Funktion trennen und nur langwierige Aufgaben in Threads auslagern, die GUI wird dann über synchronisierte Events oder Funktionen aktualisiert.

Ich mache es so, daß ich hierfür Methoden mit Parameterübergabe entwerfe und der Thread nur die neuen Informationen übergibt (ja nach Methode synchronisiert oder über Klassen mit Getter/Setter und CriticalSections oder MRSW). Die GUI Aktualisierung erfolgt dann hauptsächlich automatisch z.B. über ActionListen-Updates.

Aber grob gesagt muß alles aus der VCL von Threads aus synchronisiert werden. Dafür ist es unerheblich, ob andere Threads "in while Schleifen" stecken und nichts machen. Es ist ja trotzdem nicht der Mainthread der da auf die VCL zugreift.

Gruß Assertor

QuickAndDirty 9. Mär 2009 15:39

Re: VCL Zugriffe in Multithread Anwendung absichern
 
Ja, also wir locken Multiplen Zugriff eigentlich bereits manuell über eine Queue.
Dann hängen in dem Moment mehrere Threads und warten auf einen...dies betrifft nur die sensitiven Funktionen
(es handelt sich um eine Datenbank Anwendung). So können die Anderen zugriffe an den Wartenden threads vorbei
parallel verarbeitet werden.

Das trennen von 700k+ Zeilen Code wird jetzt nicht mal eben so zu bewerkstelligen sein, und diese Fehler treten ca. alle 2 Monate 1 mal auf. Dann aber oft mehrmals an einem Tag.
Und der Letzte Fehler geschah im debuggen beim setzen von SetTextheight eines Labels während der Dialog geladen wurde...

Ich versuche also erstmal Synchronize, wir arbeiten sowieso daran schritt für Schritt MVC-Trennung zu erreichen.

Assertor 9. Mär 2009 15:43

Re: VCL Zugriffe in Multithread Anwendung absichern
 
Hi,

Zitat:

Zitat von QuickAndDirty
Das trennen von 700k+ Zeilen Code wird jetzt nicht mal eben so zu bewerkstelligen sein, [...]
Ich versuche also erstmal Synchronize, wir arbeiten sowieso daran schritt für Schritt MVC-Trennung zu erreichen.

Absolut richtiger Weg, klar kann man so viel Produktiv-Code nicht mal eben umstellen. Die Trennung nach und nach halte ich für sinnvoll, erleichtert ja auch die Wartung über Jahre.

Im Idealfall kann man dann z.B. sogar bei einem eventuellen Programmiersprachenwechsel für andere Betriebssysteme die Funktionen schnell nachbilden und muß "nur" eine weitere GUI entwerfen.

Gruß Assertor

QuickAndDirty 10. Mär 2009 09:02

Re: VCL Zugriffe in Multithread Anwendung absichern
 
ja in der Theorie...in der Praxis hängt dann vieles an den Borland/Inpries/Codegear/libraries....und etlichen
dritten QR-Soft, TMS, IP, Eleveatsoft......

QuickAndDirty 10. Mär 2009 10:52

Re: VCL Zugriffe in Multithread Anwendung absichern
 
Sorry wegen des doppel Posts...

Arrg hat sich erledigt,
Onexecute im TService Objekt ist der richtig Ort für das CheckSynchronize, scheint zumindest zu funktionieren.


// habe ich schon raubekommen
//
Zitat:

//hier ist noch ein kleines Problem dazu gekommen.

//Die Multithreading Anwendung gibts auch als Service...
//da gibts kein Application.onIdle um CheckSynchronize aufzurufen.

//Ich habe es mal über WakeMainThread versucht allerdings scheint mir danach
//die TCPIP verbindung nicht mehr zu Antworten...

//Wie mache ich es wenn ich nicht WakeMainThread verzeigern möchte?
//Kann es sein das WakeMainthread in Dienstanwendungen bereits Verzeigert ist und dieser Zeiger nun fehlt?


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:05 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