AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Thread Anfängerfrage

Ein Thema von Spurius · begonnen am 22. Nov 2003 · letzter Beitrag vom 27. Nov 2003
Antwort Antwort
Seite 4 von 5   « Erste     234 5      
Spurius

Registriert seit: 19. Aug 2003
294 Beiträge
 
Delphi 7 Professional
 
#31

Re: Thread Anfängerfrage

  Alt 26. Nov 2003, 19:05
Ok, wenns nicht anders geht, soll ich einfach den code nehmen, den du schonmal gepostet hast?
und was ist da der Unterschied zu meinem? Ich mein, warum sollte das nicht einfrieren?
Gruß
Spurius
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#32

Re: Thread Anfängerfrage

  Alt 26. Nov 2003, 19:16
Spurius, der von mir gepostete Code war bewusst exemplarisch und kann nicht funktionieren, weil es die Eigenschaft HasData in der Klasse TidTCPClient nicht gibt!
Was Du als "einfrieren" beschreibst, sollte eigentlich ein Abbruch des Kompilerlaufs sein, der Dich auf diese Tatsache aufmerksam macht. In der OH findest Du eine Übersicht der zur Verfügung stehenden Eigenschaften und in einem Buch bestimmt auch Lösungen inkl. Beispiele für viele Grundsatzfragen zu Pascal/Delphi...
gruß, choose
  Mit Zitat antworten Zitat
Kamil

Registriert seit: 17. Aug 2002
178 Beiträge
 
#33

Re: Thread Anfängerfrage

  Alt 26. Nov 2003, 19:27
Der Unterschied liegt vorallem an UpdateMemo, das über Synchronize aufgerufen wird.
In dieser Funktion sollten keine blockierenden Aufrufe (wie z.B. TIdTCPClient.Readln, Sleep) stehen, da der Code nicht im Thread ausgeführt wird zu dem er gehört, sondern im Hauptthread deiner Anwendung, was natürlich deine Anwendung dann einfriert.

Vielelicht hilft dir das ein wenig:
Code:
 läuft im                   läuft im
Hauptthread                 MyThread
     |
     |
     |---->TMyThread.Create---->|
     |                          |
     |                          |
     |                          |
     |                          |
     | |<---Synchronize<--------|
     | |
     | |
     | | Ende von Sync. ------->|
     |                          |
     |                          |
     |                          |
     |                          |
     V                         V
Schau dir mal dieses Tutorial an:
http://www.tutorials.delphi-source.de/threads/
  Mit Zitat antworten Zitat
Spurius

Registriert seit: 19. Aug 2003
294 Beiträge
 
Delphi 7 Professional
 
#34

Re: Thread Anfängerfrage

  Alt 26. Nov 2003, 19:57
Hallo,
könnt ihr mir nicht einfach sagen, wie ich das machen soll?
Wo liegt denn mein Fehler?
Im mainthread oder in mythread?
Gruß
Spurius
  Mit Zitat antworten Zitat
Kamil

Registriert seit: 17. Aug 2002
178 Beiträge
 
#35

Re: Thread Anfängerfrage

  Alt 26. Nov 2003, 21:20
Wie sieht dein Code vom Thread gerade aus?
Wahrscheinlich ist der Fehler, dass der Code aus dem Thread im Hauptthread ausgeführt wird.
Oder hast du es schon so gemacht wie ich es gepostet habe?
  Mit Zitat antworten Zitat
Spurius

Registriert seit: 19. Aug 2003
294 Beiträge
 
Delphi 7 Professional
 
#36

Re: Thread Anfängerfrage

  Alt 27. Nov 2003, 13:49
Hallo,
das ist meinThreadcode:
Delphi-Quellcode:
unit threadtest;

interface

uses
  Classes,idtcpclient,dialogs,StdCtrls,sysutils;

type
  tmythread = class(TThread)
  private
    fclient:tidtcpclient;
    fmemo:tmemo;
    procedure updatememo;
  protected
    procedure Execute; override;
  public
   constructor create(const aclient: tidtcpclient;
   const amemo: tmemo);

  end;

implementation
uses modul;

constructor tmythread.create(const aclient: tidtcpclient;
         const amemo: tmemo);
begin
 inherited create(true);
 fclient := aclient;
 fmemo := amemo;
 resume;
end;

procedure tmythread.Execute;
begin
 while not terminated do
   if fclient. then //<- hasdata ???
   synchronize(updatememo)
  else
   sleep(100);
end;


procedure tmythread.updatememo;
begin

 fmemo.Lines.Append(fclient.ReadLn);
end;
end.
Was ist in deinem Code wesentlich anders? Oder was soll ich ändern?
Gruß
Spurius
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#37

Re: Thread Anfängerfrage

  Alt 27. Nov 2003, 14:02
Das Problem ist, wie Kamil bereits beschrieben hat, dass ReadLn geblockt ist, also die "Programmzeile so lange wartet bis tatsächlich ein String ankommt". Mit Syncronize wechselst Du in den Haupthread, so dass die Idee des Threads, nämlich diese Wartezeit unabhäng vom Hauptthread zu verbringen, untergraben wird...
Bei meiner exemplarischen Darstellung habe ich diesen Effekt durch eine fiktive Methode/Eigenschaft HasData kompensiert, die solange False zurückgibt, bis tatsächlich Daten vorhanden sind, so dass ReadLn niemals warten würde.
Die Schleife
Delphi-Quellcode:
while not Terminated do
  if FClient.HasData then
    Synchronize(UpdateMemo)
  else
    Sleep(100);
entspricht demnach im Wesentlichen einem Polling (tatsächlich nicht wirklich elegant).
Um das Ganze in den Griff zu bekommen, solltest Du innerhalb von Execute eine Exemplar-Variable mit dem Ergebnis von ReadLn füllen und erst anschließend Synchronize aufrufen, also in etwa so
Delphi-Quellcode:
while not Terminated do
begin
  FReceivedString:= FClient.ReadLn;
  Synchronize(UpdateMemo);
end;
Beachte, dass Du innerhalb von UpdateMemo diese Exemplarvariable anstatt FClient verwendest!

Nachteil dieses Ansatzes ist die Tatsache, dass ReadLn per default "unendlich lange" wartet, Du also keine saubere Möglichkeit hast, den Thread zu beenden. Hier könnte ggf doch eine Variante des Pollings verwendet werden, damit zyklisch Terminated abgefragt wird...
gruß, choose
  Mit Zitat antworten Zitat
Spurius

Registriert seit: 19. Aug 2003
294 Beiträge
 
Delphi 7 Professional
 
#38

Re: Thread Anfängerfrage

  Alt 27. Nov 2003, 14:37
Hallo,
ich hab nochmal deinen Code hier:
Delphi-Quellcode:
Source:
type
  TMyThreadClass = class(TThread)
  private
    FClient : TSomeClient;
    FMemo : TSomeVCLControl;
    procedure UpdateMemo;
  protected
    s: string;
    procedure Execute;override;
  public
    constructor Create(Host: string; Port: integer; const AMemo: TSomeVCLControl);
  end;


constructor TMyThreadClass.Create(Host: string; Port: integer; const AMemo: TSomeVCLControl);
begin
  inherited Create(True);
  Assert(Assigned(AMemo));

  FClient:= TIdTCPClient.Create(nil);
  FClient.Host:=Host;
  FClient.Port:=Port;
  //copy references to member vars
  FMemo:= AMemo;
  //start thread
  Resume;
end;

procedure TMyThreadClass.Execute;
begin
  try
    FClient.Connect;
    while (not Terminated) and (FClient.Connected) do
    begin
      s:=FClient.Readln;
      Synchronize(UpdateMemo);
    end;
  finally
    FClient.Free;
  end;
end;

procedure TMyThreadClass.UpdateMemo;
begin
  //will be executed within the mainthread
  FMemo.Lines.Append(s);
end;
hier wird ja ein client created, was hat der mit meinem tatsächlichen client im mainthread zu tun?
und wenn ich den create, muss ich ja auch dafür port und host festlegen. aber die werden ja im mainthread über edits festgelegt. wie bekomm ich da werte?
Gruß
Spurius
  Mit Zitat antworten Zitat
Kamil

Registriert seit: 17. Aug 2002
178 Beiträge
 
#39

Re: Thread Anfängerfrage

  Alt 27. Nov 2003, 15:56
Zitat:
hier wird ja ein client created, was hat der mit meinem tatsächlichen client im mainthread zu tun?
natürlich nichts!
Zitat:
und wenn ich den create, muss ich ja auch dafür port und host festlegen. aber die werden ja im mainthread über edits festgelegt. wie bekomm ich da werte?
die Werte übergibst du mit Hilfe der Parameter von dem Konstruktor.

Zitat:
Nachteil dieses Ansatzes ist die Tatsache, dass ReadLn per default "unendlich lange" wartet, Du also keine saubere Möglichkeit hast, den Thread zu beenden. Hier könnte ggf doch eine Variante des Pollings verwendet werden, damit zyklisch Terminated abgefragt wird...
Das solltest du nicht unbeachtet lassen!!! Schau dir die Parameter von ReadLn an!
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#40

Re: Thread Anfängerfrage

  Alt 27. Nov 2003, 16:14
Zitat von Kamil:
Zitat von choose:
Hier könnte ggf doch eine Variante des Pollings verwendet werden, damit zyklisch Terminated abgefragt wird...
Das solltest du nicht unbeachtet lassen!!! Schau dir die Parameter von ReadLn an!
Hallo Kamil,

könntest Du kurz skizzieren, wie Du ohne Polling (sprich: ATimeOut<>IdTimeoutInfinite) den Thread sauber terminierst (if Self.Terminated) und trotzdem jedes Byte von FClient empfängst?
gruß, choose
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 5   « Erste     234 5      


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 22:27 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