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 Frage zu TCriticalSection (https://www.delphipraxis.net/121322-frage-zu-tcriticalsection.html)

Errraddicator 25. Sep 2008 16:57


Frage zu TCriticalSection
 
Hiho,

ich habe 1 Programm, das aus 1 Fenster und 2 dazugehörigen Threads besteht.
Das Fenster erstellt anfangs eine Liste (clientList) an Mandanten, die verarbeitet werden sollen.
Dann erzeugt es 2 Threads (TWorkerThread) welche dann diese Liste abwechselnd abarbeiten sollen.

Jetzt habe ich im Fenster 2 Funktionen, auf die die Beiden Threas zugreifen müssen.
- function TfrmMain.getNextClient(): String;
Diese Funktion gibt den 1. Eintrag aus clientList zurück und löscht diesen dann aus der Liste.
Diese Funktion soll halt so lange von beiden Threads in beliebiger Reihenfolge aufgerufen werden,
bis die Liste abgearbeitet ist.

- procedure TfrmMain.updateStatus(msg: String; panelNr: Integer);
Diese Funktion schreibt wie der Name sagt einen String in das Panel <panelNr> der TStatusBar.
Jeder Thread hat dabei 1 eigenes Panel, in das er Statusmeldungen schreibt.

In welcher Form muss ich da jetzt Critical Sections einbinden, dass sich die Threads nicht beim Zugriff auf diese beiden Funktionen behaken, sondern wie gewünscht funktionieren?

...

Ich hab zuerst versucht, die TCriticalSection in den entsprechenden Funktionen selbst einzubinden.
Das funktioniert dann 1, 2 x und dann hängt sich das Programm beim Aufruf dieser Funktionen auf.

Dann habe ich es versucht, die CriticalSection in meiner Thread.Execute() Funktion um die Funktionsaufrufe drumherum zu setzen, aber dann funktioniert das gar nicht mehr.

Hat wer ne Idee?


Besten Dank im Voraus

cu Patrick

sirius 25. Sep 2008 17:02

Re: Frage zu TCriticalSection
 
1. Warum nimmst du hier nicht synchronize?

2. Du musst due CriticalSections an den Anfang und das Ende der Methoden setzen. Die CS dürfen aber nicht lokal definiert sein.
Edit: Und natürlich ein try..finally drumherum

littleDave 25. Sep 2008 17:04

Re: Frage zu TCriticalSection
 
Wenn du von einem Thread aus auf die VCL-Komponenten zugreifen willst, solltest du Delphi-Referenz durchsuchenSynchronize verwenden. CriticalSections reichen da nicht ganz aus (imho)

Edit: :gruebel: kein roter kasten

sirius 25. Sep 2008 17:08

Re: Frage zu TCriticalSection
 
Zitat:

Zitat von littleDave
CriticalSections reichen da nicht ganz aus (imho)

Ahja, das stimmt. Mit den CS tust du ja nur deine beiden Threads synchronisieren. du schaffst es aber niemals auch die VCL damit zu synchronisieren, dazu musst du schon den Mainthread anhalten (->synchronize)

Apollonius 25. Sep 2008 17:29

Re: Frage zu TCriticalSection
 
Hier ist vielleicht sogar TThread.Queue besser als TThread.Synchronize. Der Thread muss ja nicht warten, bis die Statusmeldung eingetragen ist.

sirius 25. Sep 2008 17:35

Re: Frage zu TCriticalSection
 
Zitat:

Zitat von Apollonius
Hier ist vielleicht sogar TThread.Queue besser

Was ist das? --> Google -->
Zitat:

It is a somewhat newer method, so not so many Delphi developers are
aware of it.
Kennt mein D7 nicht :(

Apollonius 25. Sep 2008 17:40

Re: Frage zu TCriticalSection
 
Hm. TThread.Queue funktioniert ähnlich wie Synchronize, wartet jedoch nicht darauf, dass der Hauptthread die Beendigung der Bearbeitung der Methode meldet.

sirius 25. Sep 2008 17:46

Re: Frage zu TCriticalSection
 
Ja, die Online-Hilfe hat mir das mittlerweile auch schon gesagt. ;)

Errraddicator 25. Sep 2008 17:48

Re: Frage zu TCriticalSection
 
Zuerst hatte ich es auch mit Synchronize probiert, aber ich hab irgendwo im Netz (hier ??? ) gelesen, dass Synchronize ab Delphi6 wohl Probleme machen würde und man statt dessen Critical Section nehmen sollte...

D.h. ich muss jetzt wie vorgehen?
Die beiden Funktionen innerhalb des Freds mit Synchronize aufrufen und die Critical Section-Geschichte komplett vergessen?
Oder beides zusammen verwenden?

...

Ausserdem hatte ich noch ein Problem mit Synchronize:
TfrmMain.getNextClient() gibt mir ja nen String zurück und wenn ich diese Funktion jetzt mit Synchronize aufrufe:
Wie komm ich denn da an den Rückgabewert?

sirius 25. Sep 2008 17:57

Re: Frage zu TCriticalSection
 
1. Synchronize macht Probleme. Zum Beispiel und vorwiegend in einer DLL. Da funktioniert es nämlich nicht. Ansonsten ist es ganz ok.

2. Du musst dir eine Hilfmethode in deine Threadklasse bauen. die rufst du über synchronize auf und die kann dann deine Zielmethode aufrufen und die Variablenübergabe erledigen

3. alternavtie zu Synchronize (Vielleicht klappt es ja)

Errraddicator 29. Sep 2008 07:07

Re: Frage zu TCriticalSection
 
Nachtrag der Drölfzigste:
Hat sich alles erledigt.
Habs mittlerweile rausgefunden, hatte noch ein paar Fehler drinne im Hauptformular und ... ganz große Idee :wall: ... zu Testzwecken nen Sleep(1000) und wunder mich, warum dass alles so ewig lange dauert... :mrgreen: :mrgreen: :mrgreen:

Naja jetzt funzt es & Danke für die Hilfe. :)

Errraddicator 29. Sep 2008 14:00

Re: Frage zu TCriticalSection
 
Toll, jetzt hatte ich die Threads an sich soweit, aber wenn ich dem Ganzen Funktionalität gebe klatscher weg. :D

...

Zitat:

Zitat von sirius
1. Synchronize macht Probleme. Zum Beispiel und vorwiegend in einer DLL. Da funktioniert es nämlich nicht. Ansonsten ist es ganz ok.

Was muss ich mir denn darunter vorstellen / wie äusser sich der Fehler?
Könnte nämlich sein, dass bei mir genau dieser Fehler auftritt.

Lese halt jetzt mit 2 Threads Daten über eine Schnittstelle (separate Software / DLL´s) aus einer Datenbank und mittendrin bekomme ich dann hin und wieder ne singemäße Fehlermeldung "Zugriffsverletzung in DLL xyz.dll ...".

Hat das vielleicht was damit zu tun?

Errraddicator 29. Sep 2008 14:31

Re: Frage zu TCriticalSection
 
Ok, auch das hat sich erledigt...
Ich habe mit dem Hersteller der Datenbank-Anbindung gesprochen und die sagten mir, diese sei wohl nicht multi-threading fähig.

Ich sollte es also anstelle von 1 Programm mit 2 Threads doch mit 2 Instanzen von 1 Singelthreadprogramm versuchen.
Da habe ich dann auch noch ne Frage zu, aber das hat hiermit dann ja nix mehr zu tun, also mache ich dafür nen Extra-Thema auf. :)


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