Entwickler-Ecke
Internet / Netzwerk - [TIdTCPServer] Threads in OnExecute
BattleFrog - Mi 18.01.06 17:12
Titel: [TIdTCPServer] Threads in OnExecute
Ich habe folgenden Code:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| TServer = class FTCPServer: TIdTCPServer; ... private procedure HandleOnExecute(AThread: TIdPeerThread); procedure Foo; ... end;
... FTCPServer.OnExecute := HandleOnExecute; ...
procedure TServer.HandleOnExecute(AThread: TIdPeerThread); begin Foo; end;
procedure TServer.Foo; begin ... end; |
Ist diese Konstuktion Thread sicher, oder ist der Aufruf von Foo ein Fehler, der bei gleichzeitigen OnExecute Ereignissen ne Exception verursacht?
Wie kann ich aus der OnExecute korrekt Proceduren aufrufen?
UGrohne - Mi 18.01.06 21:13
Mit dem jetzgen Code ist der Aufruf thread-safe, da du in foo ja nichts machst. Jetzt kommt es darauf an, was Du dort genau machst. Wenn Du z.B. globale Variablen verwendest, dann musst Du mit Hilfe einer Critical Section gleichzeitige Zugriffe verhindern.
BattleFrog - Do 19.01.06 13:38
Also in der Foo (Is ja nur ein Beispiel) wird eine Ereignisprozedur aufrufen, um dem Hauptthread (GUI) ein Ereignis zu melden, das zum Update einiger GUI-Elemente führt.
Und es hat sich in einem Test als garnicht sicher rausgestellt :)
CriticalSection hat erstmal zu keiner Verbesserung geführt
Ich werde jetzt TThread benutzen, da es dort die Synchronize Methode gibt.
Dafür muss natürlich einiges umgebaut werden im Code.
UGrohne - Do 19.01.06 17:51
Ohne Code kann ich da natürlich gar nichts dazu sagen. Meine Glaskugel liegt in Deutschland und ich glaube, die hätte mir auch nicht gesagt, was Du in foo machst :roll:
Und richtig angewendet bringt die Critical Section die Abhilfe ...
BattleFrog - Fr 20.01.06 13:22
Also Gut, ich schaffs net alleine.
Es existiert eine Form mit einem Memo (meDebugLog).
Zur Laufzeit wird ein TServer Objekt erstellt und von draussen senden TCP Clients ihr Anfragen.
Bei jeder Anfrage eines Clients tritt das Ereignis OnExecute des TCP Servers ein, damit man da seinen Code reinhauen kann um zu reagieren und zu verarbeiten.
Soweit kein Probleme.
Hier der Code reduziert auf das wesentliche:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
| TDebugEvent = procedure (Text: string);
TServer = class FTCPServer: TIdTCPServer; FOnDebug: TDebugEvent; private procedure HandleOnExecute(AThread: TIdPeerThread); procedure Debug(Text: string); public constructor create; property OnDebug: TDebugEvent read FOnDebug write FOnDebug; end;
constructor TServer.create; begin FTCPServer.OnExecute := HandleOnExecute; end;
procedure TServer.HandleOnExecute(AThread: TIdPeerThread); begin Debug('Debugmeldung...'); end;
procedure TServer.Debug(Text: string); begin if assigned(FOnDebug) then FOnDebug(Text); end; |
Das OnDebug Ereignis is dazu da, damit die Form die Debugmeldungen in das Memo schreiben kann.
Das klappt auch, solange nicht zu viele Clients gleichzeitig Anfragen senden.
Und meine Vermutung war, das es mit den vielen Threads zu tun hat, die gleichzeitig das Ereignis OnExecute auslösen, in dem wiederum das Ereignis OnDebug ausgelöst wird.
Edit:
OnExecute wird ja selbst aus einem Thread (TIdPeerThread) aufgerufen, ohne eine Critical Section zu benutzen.
Kann man eine Critical Section auch im Hauptthread (Formulare usw) erstellen und so alle anderen "echten" Threads blockieren?
UGrohne - Fr 20.01.06 20:16
BattleFrog hat folgendes geschrieben: |
Kann man eine Critical Section auch im Hauptthread (Formulare usw) erstellen und so alle anderen "echten" Threads blockieren? |
Klar kannst Du das. Du kannst also beispielsweise in Deinem Formular, wo das Event verarbeitet wird eine CS einsetzen. Einfach wird es aber wahrscheinlich sein, wenn Du eine CS einfach in Deiner TServer-Klasse implementierst und den Aufruf des Events in Debug in diese CriticalSection setzt. Das sollte IMHO funktionieren.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!