Einzelnen Beitrag anzeigen

Bambini
(Gast)

n/a Beiträge
 
#16

AW: TIdTCPServer (Indy) und TClientSocket

  Alt 17. Nov 2016, 11:49
Das isz jetzt zwar OT: aber wenn ich das richtig deute, muss ich dann auch VCL-Zugriffe in allen TIdTCPServer-Ereignissen entsprechend absichern? Das ist ein ganz schöner Overhead, finde ich.
Ich vermisse dann auch einen Compiler-Hinweis. Der "liest" ja den Code und sollte das wissen
Wer welchen Code zur Laufzeit aufruft, kann der Compiler nicht sehen und daher nicht helfen.
Ich habe in meinem Thread das Ereignis aus dem Thread heraus threadsicher (hoffe ich) aufgerufen. Warum machen das die Indys nicht gleich so? Und was mache ich, wenn die Prozeduren größer als eine klitzekleine Ausgabe in der GUI werden? ...
Das bremst die Clients nebeneinander aus. Wenn Client1 in OnExecute() einen größeren Job zu erledigen hat, dann kann kein weiterer Client etwas machen.
Daher ist es schon sehr gut, dass die für jeden Client im eigenen Thread läuft.
Ich will nur sagen, dass das OnExecute() from TidTCPIPServer von einem Thread aus gerufen wird. Das macht die Komponente schon ganz alleine. Jedoch muss man dann aufpassen, das deine Code dann Threadsicher ist. D.h. Zugriffe auf Globale Variablen und UI sind zu synchronisieren (s.o.)
Aber dass das Ereignis aus einem Thread aufgerufen wird, macht es doch nicht automatisch threadunsicher, wenn es sauber programmiert wurde. Ich dachte immer, so wäre es richtig und alle schlauen Ersteller von Komponenten würden das so (richtig) machen:
Delphi-Quellcode:
// Völlig ungetestet zusammengeschrieben, um die Frage zu verdeutlichen!!!
type
   TfoobarEvent   = procedure (Value: Integer) of object;

   foobar = class(TThread)
   private
      FValue      : Integer;
      FOnErgebnis   : TfoobarEvent
      Procedure FireThreadSafe;
   protected
      procedure Execute; override;
   public
      property OnErgebnis: TfoobarEvent read FOnErgebnis write FOnErgebnis;
   end;

implementation

procedure foobar.FireThreadSafe;
Begin
   if Assigned(FOnErgebnis) then FOnErgebnis(FValue);
End;

procedure foobar.Execute;
begin
   while not Terminated do
   begin
      FValue:= Random(5000);
      if (FValue = 0) then Synchronize(FireThreadSafe);
   end;
end;
In diesem Fall muss ich dann innerhalb des VCL-Teils kein Syncronize mehr benutzen, oder doch?
Ich bin jetzt etwas verwirrt.
Nein muss du dann nicht mehr. Einmal Synchronize reicht.
  Mit Zitat antworten Zitat