Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi IdTCPServer - OnExecution und GUI Zugriffe (https://www.delphipraxis.net/124938-idtcpserver-onexecution-und-gui-zugriffe.html)

moelski 27. Nov 2008 14:19


IdTCPServer - OnExecution und GUI Zugriffe
 
Moin !

Ähnlich wie bei den Pipes stosse ich auch beim iDTCPServer auf ein kleines Problem. Und zwar habe ich folgenden Code:
Delphi-Quellcode:
procedure TfrMain.IdTCPServer1Execute(AContext: TIdContext);
var
  request :string;
begin
  request := acontext.Connection.IOHandler.ReadLn;

  Daten := request;

  DecodeCommands;
end;
Daten ist ein globaler String den ich in DecodeCommands auswerte. Dort werden z.B. MDI Childfenster erzeugt.
aber die Anwendung hängt beim Ausführen von DecodeCommands.

Bei meinem Pipe Problem konnte ich das (weil es im Thread läuft) mittels Sychronize lösen. Aber das scheint hier nicht zu klappen. Was muss ich also beim TCPServer tun um mit meiner GUI interagieren zu können beim Execute?

Harry M. 27. Nov 2008 14:44

Re: IdTCPServer - OnExecution und GUI Zugriffe
 
Ebenfalls mit Syncornize des mit dem TCP-Thread des Servers nicht Deines Threads.

Oder mit einer CriticalSection bzw RTL_CriticalSection.

Gruß Harry

PS: und nicht vergessen die CS wieder laufen zu lassen mit CriticalSection.Leave ;)

moelski 27. Nov 2008 14:47

Re: IdTCPServer - OnExecution und GUI Zugriffe
 
Und wie sieht das praktisch aus?

IdTCPServer1.Synchronize gibt es nicht :gruebel:

ChrisE 27. Nov 2008 14:59

Re: IdTCPServer - OnExecution und GUI Zugriffe
 
Hallo,

also ich würde die Daten in einen Buffer schreiben (Array[0..X] of String oder so (genug Plätzte für ca. 2 Sekunden) vielleicht mit TCriticalSection oder so) und dann nicht die Methode direkt aufrufen sonder per Postmessage das Fenster informieren und dort den Index des eben eingetragenen Strings übergeben.

Das sollte gehen.

Gruß, Chris

Edit für Praktisch:
Delphi-Quellcode:
procedure TfrMain.IdTCPServer1Execute(AContext: TIdContext);
var
  request :string;
  naechsterIndex: Integer;
begin
  request := acontext.Connection.IOHandler.ReadLn;
  MyCriticalSection.Enter;
  try
    naesterIndex := (letzterInd +1) mod MAXINDEX_BUFF;
    letzterInd := naesterInd;
    MyDatenArr[naesterIndex] := request;
    PostMessage(Form.Handle, WM_DODECODE_COMMANDS, 0, naesterInd);
  finally
    MyCriticalSection.Leave;
  end;
end;

Harry M. 27. Nov 2008 15:13

Re: IdTCPServer - OnExecution und GUI Zugriffe
 
Delphi-Quellcode:
procedure TForm1.myProc;
begin
  ///..
end;

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
begin
  AThread.Synchronize(myProc);
end;
oder
Delphi-Quellcode:
uses
SyncObjs;

var
  CS: TCriticalSection;

procedure TForm1.myProc;
begin
  CS.Enter;

  //...

  CS.Leave;
end;

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
begin
  myProc;
end;

littleDave 27. Nov 2008 15:21

Re: IdTCPServer - OnExecution und GUI Zugriffe
 
Zitat:

Zitat von Harry M.
oder
Delphi-Quellcode:
uses
SyncObjs;

var
  CS: TCriticalSection;

procedure TForm1.myProc;
begin
  CS.Enter;

  //...

  CS.Leave;
end;

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
begin
  myProc;
end;

Das ist nicht immer korrekt!!! Wenn man jetzt in myProc auf Label1.Caption zugreift, kann es trotzdem krachen. Sagen wir ich habe einen Timer, der jede Millisekunde die Caption von Label1 ausließt. Jetzt kommt myProc daher und ändert Label1.Caption. Jetzt wird der Hauptthread (mit dem Timer) aber von der CriticalSection nicht angehalten, wodurch zwei Methoden gleichzeitig auf ein Objekt zugreifen könnten. Es muss ja nichtmal nen Timer sein, es kann ja auch einfach nur die Paint-Methode sein, falls das Fenster gerade nicht sichtbar war.

Sobald man auf die VCL zugreift, muss man in 99,8% aller Fälle Synchronize() verwenden.

Zudem ist es wirklich nur zu empfehlen, die Critical-Section mit einem try-finally-Block zu versehen:
Delphi-Quellcode:
procedure TForm1.myProc;
begin
  CS.Enter;
  try
    //...
  finally
    CS.Leave;
  end;
end;
Sonst kann es zu Dead-Locks kommen (mehrere Threads warten gleichzeitig auf einen anderen Thread)

moelski 27. Nov 2008 15:39

Re: IdTCPServer - OnExecution und GUI Zugriffe
 
Moin !

Ok, bleibt im Moment noch eine Frage ...

Meine Execution Methode ist so deklariert:
procedure TfrMain.IdTCPServer1Execute(AContext: TIdContext);

Und nicht mit ....IdTCPServer1Execute(AThread: TIdPeerThread); :gruebel:

Harry M. 27. Nov 2008 15:56

Re: IdTCPServer - OnExecution und GUI Zugriffe
 
Unterschiede in der IndyVersion 8 / 9 / 10
Aber von Prinzip das Gleiche

[dekphi]
AContext.Syncronisze
// oder
AContext.Connection.Syncronisze

[/delphi]

moelski 27. Nov 2008 15:59

Re: IdTCPServer - OnExecution und GUI Zugriffe
 
Moin !

Nö das hab ich schon durch.

AContext.Syncronisze
// oder
AContext.Connection.Syncronisze

Hat beides keine Methode Synchronize :cry:

Harry M. 27. Nov 2008 16:06

Re: IdTCPServer - OnExecution und GUI Zugriffe
 
@littleDave

Dann muss die CS natürlich auch in den Timer.

@moelski
Delphi-Quellcode:
AContext.Connection.Socket.Syncronisze
// oder
AContext.Socket.Connection.Syncronisze
Das ist irgendwo versteckt, aber vorhanden.


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