AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Threads und Zugriff auf VCL-Komponenten
Thema durchsuchen
Ansicht
Themen-Optionen

Threads und Zugriff auf VCL-Komponenten

Ein Thema von DataCool · begonnen am 15. Mai 2003 · letzter Beitrag vom 16. Mai 2003
Antwort Antwort
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#1

Threads und Zugriff auf VCL-Komponenten

  Alt 15. Mai 2003, 22:01
Hi Leute,

mal ne allgemeine Fragen zur Multi-Thread-Programmierung :

Situation:
Gehen wir jetzt mal von einem einfachen Chat aus.

Problem :
Ich verwende die Indy TIdTCPServer-Komponente. Jetzt bekomme ich innerhalb der OnExecute Methode des TIdTCPServer meinen AThread: TIdPeerThread innerhalb dieses Threads bekomme ich jetzt Nachrichten wie z.B. Connect UserXY, DisConnect UserXY, ChatText "ich chatte mit Dir".
Jetzt möchte aufgrund dieser Nachrichten auf meiner Main-Form reagieren.
Meldet sich ein User an, so muss der Username in einem ListView hinzugefügt werden.
Meldet sich der User ab, muß er aus dem ListView entfernt werden.
Schreibt der User etwas, so muß das natürlich dem Benutzer angezeigt werden.

Frage 1:
Wie kann ich das alles Thread sicher realisieren ? Laut Delphi-Hilfe müßte ich mit syncronize arbeiten, dabei kann ich aber keine Übergabe Parameter verwenden. Wie also sage ich meinen Thread das er dir Procedure AddUser(newUser : String) Thread-sicher ausführen soll und wie übergebe ich den Usernamen ?

Frage 2:
Oder muss ich wie im Delphi-Demo "Threads" mir meine eigene Thread-Klasse schreiben, diese innerhalb des Indy-Threads mit den benötigten Parametern(z.B. ListBox und Memo) erzeugen ?

Vielen Dank im Vorraus,

Data
  Mit Zitat antworten Zitat
Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#2

Re: Threads und Zugriff auf VCL-Komponenten

  Alt 15. Mai 2003, 22:20
Zitat von DataCool:
Frage 1:
Wie kann ich das alles Thread sicher realisieren ? Laut Delphi-Hilfe müßte ich mit syncronize arbeiten, dabei kann ich aber keine Übergabe Parameter verwenden. Wie also sage ich meinen Thread das er dir Procedure AddUser(newUser : String) Thread-sicher ausführen soll und wie übergebe ich den Usernamen ?
Indem du die Variable newUser als private in deiner Threadklasse deklarierst. Bevor du also synchronize aufrufts, setzt du deine private Eigenschaft mit dem gewünschten Wert.

Gruss,
Tom
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#3
  Alt 16. Mai 2003, 00:37
Hi,

aber ich habe ja keine eigene Thread-Klasse !
Ich erhalte den Thread ja im Ereignis OnExecute des TIdTCPServers(TIdPeerThread).
Darauf bezieht sich meine zweite Frage, soll ich mir eine eigene Thread-Klasse schreiben, die so vorgeht wie Du beschrieben hast?
Und dann in jedem TIdPeerThread einen myXYThread erzeugen ?

Das ist auch das was ich mit Frage zwei meinte !

Gruß Jan
  Mit Zitat antworten Zitat
Benutzerbild von OrallY
OrallY

Registriert seit: 29. Apr 2003
268 Beiträge
 
#4
  Alt 16. Mai 2003, 14:59
Ich verstehe ehrlich gesagt nicht, wo das Problem ist?
Du kannst doch im OnExecute-Event einfach die AddUser(newUser : String) Prozedur aufrufen, die als Public in deiner Mainformklasse deklariert ist. Auf jedenfall musst du da nichts mit Synchronize aufrufen! Das müsstest du nur, wenn du in einem "echten" Thread eine Prozedur des MainThreads aufrufen willst.
Wenn du Synchronize benutzen willst (Synchronize tut nichts anderes als das Programm anzuweisen, den Mainthread zu benutzen), benutzt man im Allgemeinen sog. Wrapper. Das ist eine Prozedur, die den Aufruf der Prozedur übernimmt (wrapper werden meistens nur im Zusammenhang von Ereignisbehandlungsroutinen verwendet). Ein Beispiel:
Delphi-Quellcode:
procedure TMyThread.mAddUser;
begin
   AddUser(aname);
end;

procedure TMyThread.Execute;
begin
   Synchronize(mAddUser);
end;
Aber IMHO ist Synchronize bei den Indys fehl am Platze!
.oO'rallY
Linux is like a tipi: no gates, no windows and a gnu-eating apache inside...
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#5
  Alt 16. Mai 2003, 15:39
Hi,

@OrallY:
Mein Problem besteht darin, das ich innerhalb meines Indy-Threads Methoden der Main-Form nicht Thread-sicher aufrufen kann !
Ok, das Bsp. mit AddUser sollte auch ohne Synchronize laufen, aber jetzt nimm mal z.B. DeleteUser !
Wenn ich zwei Idy-Threads im EReignis OnExecute am laufen habe und beide rufen DeleteUser der MainForm simultan auf, dann war's das
Oder noch besser, wenn ich einen Chat-Text von einem User erhalten und diesen in einen Datei speichern will und diese Datei zur Anzeige wieder laden will.
WEnn jetzt zwei Indy-Threads beide versuchen in die Datei zu Schreiben, was passiert dann ?!
Deshalb sollte ich auf jeden Fall mit Synchronize arbeiten, die Frage ist nur wie !
Innerhalb des Indy-Threads kann ich nicht Synchronize(addUser('Karl')); aufrufen. DA Synchronize ja nicht mit Parametern aufgerufen kann.

Deshalb jetzt meine Überlegung :
Ich schreibe meine eigene Thread-Klasse myAddThread, myDelThread u. myChatThread.
Innerhalb des Indy-Threads lese ich die Nachricht des Clients aus und erzeuge dann anhängig von der Nachricht einen myAddUserThread, myDelThread oder myChatThread, die dann auch ohne Frage die VCL-Komponenten thread-sicher aufrufen können.

Ich wollte jetzt nur wissen, ob das der richtige Denkansatz ist, oder sollte ich das besser anders realisieren ?

Gruß,

Data
  Mit Zitat antworten Zitat
Benutzerbild von OrallY
OrallY

Registriert seit: 29. Apr 2003
268 Beiträge
 
#6
  Alt 16. Mai 2003, 20:14
Wie ich schon schrieb: Mittels Wrapper ist es möglich mit Synchronize Paramater zu benutzen. Ein Wrapper ist eine Prozedur, ohne Parameter, die die wiederum die gewünschte Prozedur aufruft, mit den entsprechenden Parametern. Dazu kannst du z.B. die Parameter vor dem Aufruf von Synchronize in Variablen speichern und dann diese Variablen im Wrapper benutzen. So z.B.:
Delphi-Quellcode:
procedure TForm1.AddUser(name: string; id: integer);
begin
   ListBox1.Add(aname);
   ...
end;

//globale Variablen die als temporärer Speicher der Parameter verwendet werden
var
   aname: string;
   aid: integer;

procedure TForm1.AddUserWrapper; //wrapper von AddUser
begin
   AddUser(aname, aid); //aufruf der richtigen Prozedur
end;

procedure TForm1.TIdTCP....Execute; //Execute der Indy
begin
  with AThread.Connection do
  begin
     aname := 'labersack'; //Wertzuweisung der "Parameter"
     aid := 7483;
     Synchronize(AddUserWrapper); //threadsicherer Aufruf der AddUser-Prozedur mittels Wrapper
  end;
end;
Code ist "OnTheFly" geschrieben.
Ich hab das jetzt sehr ausführlich gestaltet, aber bitte nicht vera***** fühlen. Ich gehe eigentlich davon aus, dass du recht viel Ahnung hast; doch besser ein wenig ausführlicher als zu schlecht erklärt!

Somit müsstest du dein Problem eigentlich lösen können. Eigene Threadklassen sind IMHO unnötig.
.oO'rallY
Linux is like a tipi: no gates, no windows and a gnu-eating apache inside...
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:35 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