Autor Beitrag
Yheeky
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 06.03.07 12:29 
Hi,

Ich verwende die UDPSockUtil Komponente, die hier im Forum bereitgestellt wurde (an dieser Stelle nochmal ein Lob für die tolle Komponente). Nun zu meiner Frage:
Ich will bei Button1Click eine Info an alle Teilnehmer schicken, deren IP-Adressen in der ListView1 stehen. Bisher geht das zwar, aber es dauert ca. 5 Sekunden, ehe das Programm wieder reagiert. Die Funktion sieht so aus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
for User := 0 to frmMain.ListView1.Items.Count - 1 do 
begin 
UDPSockUtil1.RemoteHost := frmMain.ListView1.Items[User].SubItems[1]; 
UDPSockUtil1.SendText(Username + '#' + IntToStr(User)); 
end;


Ich denke ich weiss, wie es in der Theorie funktioniert - nämlich mit Threads - aber in der Thematik kenne ich mich nicht wirklich so gut aus. Könnte mir das vielleicht jemand anhand meinem aktuellen Problem erklären? Wäre echt nett!

Danke schonmal!

Gruß Christian

Moderiert von user profile iconmatze: Code- durch Delphi-Tags ersetzt
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Di 06.03.07 14:44 
Wenn du willst, dass das Programm weiter reagiert, während deine Nachricht gesendet wird, füge in die Schleife ein Application.ProcessMessages; ein. Dann könntest du noch eine Progressbar einfügen, mit der du den Fortschritt anzeigst, so dass der User nicht denkt, nach dem Klick wäre bereits alles erledigt.

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 06.03.07 15:07 
Moin!

Der Hinweis von user profile iconJayEff ist schon ganz gut. ;)

Ich denke, die Verzögerung kommt durch eine Hostnamenauflösung zustande (du hast eine Wählverbindung/DSL, richtig?). Wenn du die IP als Adresse verwendest, kannst du so auch nochmal Zeit "einsparen" (zumindest, wenn du die IP hast :?).

Ansonsten hilft die Idee mit dem Thread natürlich weiter, aber da die VCL nicht threadsave ist, sind so Ansätze (Liste in VCL-Kompo) immer nicht ganz leicht (und nicht in "drei Worten/Codeschnipseln") zu erklären. user profile iconLuckie hat auf seiner HP ein gutes Thread-Tutorial, vielleicht solltest du da mal reinsehen. ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Yheeky
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 06.03.07 18:02 
user profile iconNarses hat folgendes geschrieben:
Moin!

Der Hinweis von user profile iconJayEff ist schon ganz gut. ;)


Ja, hat mir auch schon ein wenig geholfen, danke!

Das eigentliche Problem ist aber immer noch da und das könnte an dem Grund liegen, den du angeführt hast:

user profile iconNarses hat folgendes geschrieben:
Ich denke, die Verzögerung kommt durch eine Hostnamenauflösung zustande (du hast eine Wählverbindung/DSL, richtig?). Wenn du die IP als Adresse verwendest, kannst du so auch nochmal Zeit "einsparen" (zumindest, wenn du die IP hast :?).

Ansonsten hilft die Idee mit dem Thread natürlich weiter, aber da die VCL nicht threadsave ist, sind so Ansätze (Liste in VCL-Kompo) immer nicht ganz leicht (und nicht in "drei Worten/Codeschnipseln") zu erklären. user profile iconLuckie hat auf seiner HP ein gutes Thread-Tutorial, vielleicht solltest du da mal reinsehen. ;)


Also vorneweg: das Tutorial von Luckie kenne ich bereits. Ich finde es aber leider nicht so verständlich, wie ich es mir wünschen würde. Ich lerne besser anhand von Beispielen. Die Beispiele von Luckie sind aber nicht so recht solche, die mir weiterhelfen. Ich stand schon öfters vor dem jetzigen Problem. Ich bin es irgendwie immer umgangen, aber dieses Mal geht´s eben nicht :-(
Kann es sein, dass es mehrere Arten von Threads gibt?
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 06.03.07 18:31 
Moin!

user profile iconYheeky hat folgendes geschrieben:
Kann es sein, dass es mehrere Arten von Threads gibt?

Hm, AFAIK nicht. Thread ist Thread. ;) Es gibt allerdings Dinge zu beachten, je nachdem, in welchem Thread-Kontext dein Code läuft (z.B. darfst du aus einem anderen als dem Hauptthread (=VCL-Thread) nicht auf die VCL zugreifen, eben nur synchronisiert).

user profile iconYheeky hat folgendes geschrieben:
Also vorneweg: das Tutorial von Luckie kenne ich bereits. Ich finde es aber leider nicht so verständlich, wie ich es mir wünschen würde.

Also ich will ehrlich sein, wenn du beim Thema Threads noch nicht soo firm bist, dann ist es sicher keine gute Idee, gleich mehrere Probleme auf einmal anzugehen (VCL-Zugriff, Synchronisation, Kommunikation). :?

Mein Vorschlag: mach doch erstmal ein paar (andere?) Tuts zum Thema Threads, versuch dich an ein paar kleineren Beispielen (aus Threads synchronisiert auf die VCL zugreifen, Datenaustausch mit Threads, etc.) und geh dann erst nochmal auf dein aktuelles Problem zu. So einfach sich dein Vorhaben auch anhören mag, letztlich ist es das leider nicht... :|

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Yheeky
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 06.03.07 18:57 
Okay...wie du meinst. Ich hätte dir nicht mal sagen können, dass ich gleich 3 Probleme auf einmal hab ;-)
Kennst du vielleicht Tuts die für Anfänger geeignet sind?
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 06.03.07 20:33 
Moin!

Schonmal in unsere Library geschaut? Wenn da nix weiter für dich bei ist (ich verweise sonst auch immer nur auf user profile iconLuckies Tut), dann habe ich auch leider sonst nix bei der Hand. :?

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Robinator
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 275

WinXP
BDS 2006
BeitragVerfasst: Di 06.03.07 20:45 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
TUDPThread = class(TTHread)
  private
    FRemoteHost : String;
    FText : String;
  protected
    procedure Execute; override;
  public
    Constuctor Create(ARemoteHost, AText : String);

constructor TUDPThread.Create(ARemoteHost, AText : String);
begin
  inherited Create(True);
  FRemoteHost := ARemoteHost;
  FText := AText;
  Suspended := false;
end;

procedure TUDPThread.Execute;
begin
  UDPSockUtil1.RemoteHost := FRemoteHost; 
  UDPSockUtil1.SendText(FText); 
end;


Ungetesten und nur so hier reingetipselt, aber als Ansatz sollte es dennoch helfen ;)

gruss, rob

_________________
erare humanum est
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 07.03.07 00:07 
Moin!

user profile iconRobinator hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
TUDPThread = class(TTHread)
  private
    FRemoteHost : String;
    FText : String;
  protected
    procedure Execute; override;
  public
    Constuctor Create(ARemoteHost, AText : String);

constructor TUDPThread.Create(ARemoteHost, AText : String);
begin
  inherited Create(True);
  FRemoteHost := ARemoteHost;
  FText := AText;
  Suspended := false;
end;

procedure TUDPThread.Execute;
begin
  UDPSockUtil1.RemoteHost := FRemoteHost; 
  UDPSockUtil1.SendText(FText); 
end;

Sorry, aber ich rate dringend davon ab, den Code so zu verwenden! :shock: :mahn:

Die Execute-Methode muss mindestens in eine CriticalSection, noch besser, einen dynamischen UDP-Socket im Thread erzeugen und nach dem Senden freigeben, um kein Chaos mit den Ereignissen zu bekommen (wenn man denn diese noch verwenden will)! Abgesehen davon würde die DNS-Auflösung ohne einen separaten UDP-Socket auch wieder nicht parallelisiert, was ja die "Zeitersparnis" bringen soll. :?

Bitte, das sieht einfacher aus, als es wirklich ist! :mahn:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.


Zuletzt bearbeitet von Narses am Mi 07.03.07 00:18, insgesamt 1-mal bearbeitet
Yheeky
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 07.03.07 00:16 
Also ich habe doch noch ein Tutorial gefunden. Dem werde ich mich morgen mal widmen.

@Robinator: Danke erstmal! Ich habe gerade mal deinen Code ausprobiert. Beim Aufruf bekomme ich jedoch eine Fehlermeldung:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure UDPSendString;
var 
  Send_Thread : TUDPThread;
  TempRemoteHost, TempText : String;
begin
TempRemoteHost := frmMain.Users.Items[User].SubItems[4];
TempText := OwnComputername;

Send_Thread.Create(TempRemoteHost, TempText);

end;


Woran könnte das liegen?

Gruß Christian

Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt
Yheeky
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 07.03.07 00:18 
Okay, habe jetzt erst leider deine Nachricht gelesen *g*...wenn´s so schwierig ist, wie soll ich das denn dann hinbekommen?! :cry:
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 07.03.07 00:24 
Moin!

user profile iconYheeky hat folgendes geschrieben:
Okay, habe jetzt erst leider deine Nachricht gelesen *g*...wenn´s so schwierig ist, wie soll ich das denn dann hinbekommen?! :cry:

So: ;)
user profile iconYheeky hat folgendes geschrieben:
Also ich habe doch noch ein Tutorial gefunden. Dem werde ich mich morgen mal widmen.

Ich habe im Verlauf dieses Themas schon alle wichtigen Hinweise gegeben (ach ja, in user profile iconRobinators Code fehlt natürlich auch noch das Freigeben des Thread-Objekts...), einfach mit der Materie vertraut machen und probieren; es ist noch kein Meister vom Himmel gefallen... ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Robinator
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 275

WinXP
BDS 2006
BeitragVerfasst: Mi 07.03.07 03:21 
user profile iconNarses hat folgendes geschrieben:
Sorry, aber ich rate dringend davon ab, den Code so zu verwenden! :shock: :mahn:


Ich hab überhaupt nichts von so verwenden gesagt, ich sagte, dass es sich bei dem code um einen Ansatz handelt (wer lesen kann ist klar im Vorteil)


user profile iconNarses hat folgendes geschrieben:
Ich habe im Verlauf dieses Themas schon alle wichtigen Hinweise gegeben (ach ja, in Robinators Code fehlt natürlich auch noch das Freigeben des Thread-Objekts...)


Der Thread gibt sich selber frei sobald er mit dem Execute fertig ist. Critical sections benötigt man im TThread für derartige dinge eigentlich nicht :). Auch geht es nicht um Zeitersparniss, sondern um das Einfrieren des Programms.




gruss, rob

_________________
erare humanum est
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 07.03.07 10:19 
Moin!

user profile iconRobinator hat folgendes geschrieben:
Ich hab überhaupt nichts von so verwenden gesagt, ich sagte, dass es sich bei dem code um einen Ansatz handelt (wer lesen kann ist klar im Vorteil)

OK, dann so: "Ich rate drigend davon ab, den Ansatz weiter zu verfolgen!" :mahn: Jetzt besser? :P

user profile iconRobinator hat folgendes geschrieben:
Der Thread gibt sich selber frei sobald er mit dem Execute fertig ist.

Ist .FreeOnTerminate default True? :gruebel: mag sein, schadet aber nicht, dass trotzdem zu setzen, finde ich. ;)

user profile iconRobinator hat folgendes geschrieben:
Critical sections benötigt man im TThread für derartige dinge eigentlich nicht :).
:arrow:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TUDPThread.Execute;  
begin  
  UDPSockUtil1.RemoteHost := FRemoteHost;
  // hier kritische Stelle
  UDPSockUtil1.SendText(FText);   
end;

Da du offensichtlich mit einem globalen UDPSockUtil arbeiten willst (ich sehe jedenfalls keinen lokalen), kann dir von der DNS-Auflösung bis zum Senden ein anderer Thread dazwischen gehen (wenn du mehrere parallel startest, ist das sogar sehr wahrscheinlich) :shock: ->Chaos! :hair: -> CriticalSection. ;)

user profile iconRobinator hat folgendes geschrieben:
Auch geht es nicht um Zeitersparniss, sondern um das Einfrieren des Programms.

Das ist in diesem Fall ursächlich das gleiche (wer lesen kann ist klar im Vorteil)... ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Robinator
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 275

WinXP
BDS 2006
BeitragVerfasst: Mi 07.03.07 13:05 
Hallo Narses,

Irgendwie leuchtet mir nicht ein was du erreichen möchtest. Ich habe doch keine fertige Lösung gepostet, nichtmal behauptet, dass der Code komplett ist habe ich :(.


user profile iconNarses hat folgendes geschrieben:

Da du offensichtlich mit einem globalen UDPSockUtil arbeiten willst (ich sehe jedenfalls keinen lokalen), kann dir von der DNS-Auflösung bis zum Senden ein anderer Thread dazwischen gehen (wenn du mehrere parallel startest, ist das sogar sehr wahrscheinlich) :shock: ->Chaos! :hair: -> CriticalSection. ;)


NEIN! Ich möchte nicht mit einem globalen UDPSockUtil arbeiten, ich weis nichtmal was ein UDPSockUtil für eine Komponente ist. Alles was ich wollte ist, ein Beispiel geben, wie man mit Threads arbeitet!

Also, ersteinmal nichts für ungut. Ich finde allerdings, das dein Ton auch etwas freundlicher ausfallen könnte (meiner im letzten Post auch, das gebe ich zu :) ).

Gruss, rob

_________________
erare humanum est
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 07.03.07 13:15 
Moin!

user profile iconRobinator hat folgendes geschrieben:
Also, ersteinmal nichts für ungut. Ich finde allerdings, das dein Ton auch etwas freundlicher ausfallen könnte (meiner im letzten Post auch, das gebe ich zu :) ).

:? Ich finde meinen Ton zwar maximal warnend, aber wenn du dir auf den Schlips getreten vorkommst, war das definitiv nicht beabsichtigt! :shock: Also, sorry. ;)

user profile iconRobinator hat folgendes geschrieben:
Irgendwie leuchtet mir nicht ein was du erreichen möchtest. Ich habe doch keine fertige Lösung gepostet, nichtmal behauptet, dass der Code komplett ist habe ich :(.
[...]
Ich möchte nicht mit einem globalen UDPSockUtil arbeiten, ich weis nichtmal was ein UDPSockUtil für eine Komponente ist. Alles was ich wollte ist, ein Beispiel geben, wie man mit Threads arbeitet!

Ich möchte erreichen, dass du keine Beispiele/Ansätze gibst, die mit den verwendeten Komponenten nicht klappen werden. ;) Du hast Recht, für einen Thread alleine ist das Beispiel/der Ansatz OK, aber eben nicht, wenn Netzwerkkommunikation ins Spiel kommt! :idea: Darauf habe ich aber auch schon vorher hingewiesen. ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Yheeky
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 07.03.07 13:49 
Also soll ich mehrere UDPSockUtils verwenden oder wie meinst du das?
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: Mi 07.03.07 13:51 
Hallo,

auf wenn Narses eigentlich schon darauf hingewiesen hat, möchte ich nochmal darauf zurückkommen: Die Verzögerung scheint ja durch die Hostauflösung zu kommen!

Deshalb könntest du ja auch einfach für jeden Hostnamen die IP-Adresse suchen und intern speichern. Damit braucht es zwar beim ersten Senden länger (außer du machst das schon davor), danach sollte es dann aber schneller gehen, womöglich so schnell, dass du gar keine Threads mehr brauchst!

Das ist dann nicht 100% professionel, aber du kannst trotzdem weiterarbeiten, warscheinlich mit einer vernünftigen Geschwindigkeit.

Viel Glück,
Hape
Robinator
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 275

WinXP
BDS 2006
BeitragVerfasst: Mi 07.03.07 13:51 
Ja, pro Thread einen ;)

_________________
erare humanum est
Yheeky
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 07.03.07 17:04 
Okay, also sollte ich vielleicht erstmal versuchen die Hostauflösung in einen Thread zu machen oder? Dann sollte das mit dem Einfrieren schonmal weg sein.
Die allgemein schlechte Performance liegt dann also daran, dass alles über eine Komponente läuft, richtig?
Ich kann natürlich für jede Verbindung einen neuen UDPSockUtil anlegen, nur wird das Ereignis OnReceiver dann ja für jede Komponente abgefragt. Sorgt das dann nicht auch für eine Programmüberlastung?