Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Thread startet nicht sofort (https://www.delphipraxis.net/107516-thread-startet-nicht-sofort.html)

zweitakt 29. Jan 2008 09:45


Thread startet nicht sofort
 
Hallo,

ich habe ein Problem mit meinem Testprogramm. Und zwar wird der Thread erst gestartet nach dem der Prozess, indem ich die Funktion Create aufrufe, beendet wurde. Laut Dokumentaion sollte der Thread aber sofort nach Aufruf von Thread.Resume starten. Hat von euch vielleicht jemand eine Idee?

Delphi-Quellcode:
procedure TTest.Execute;
begin
  try
    a := 0;
    while (a < 100) do
    begin
      inc(a);
      Form1.Memo1.Lines.Add(IntToStr(a));
      sleep(50);
    end;
  except
    on e: exception do begin
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var wf : DWORD;
begin
  Thread1 := TTest.Create(True);
  Thread1.FreeOnTerminate := True;
  Thread1.Resume;
  sleep(5000);
end;

DP-Maintenance 29. Jan 2008 09:49

DP-Maintenance
 
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "Sonstige Fragen zu Delphi" verschoben.
Delphi-Frage

generic 29. Jan 2008 10:00

Re: Thread startet nicht sofort
 
das ist nicht richtig. der thread startet sofort.
du siehst nur nicht die ausgabe des threads.

das sleep(5000) bringt den vcl thread zum schlafen, welches zu der folge hat, dass deine ausgaben nicht mehr angezeigt werden.

achtung:
die vcl ist nicht threadsafe!

wenn du im thread ausgaben in deine vcl form machen willst, dann solltest du die beiden threads syncronisieren.

Delphi-Quellcode:
Form1.Memo1.Lines.Add(IntToStr(a));
sowas direkt aufzurufen ist schlecht.

kontaktiere mal die hilfe, dort ist ein beispiel für "syncronize()" drin.

[edit]
p.s. willkommen in der dp

zweitakt 29. Jan 2008 10:08

Re: Thread startet nicht sofort
 
Erstmal danke für die schnelle Antwort. Wenn ich den Code folgendermassen ändere, ist der Effekt der gleiche, obwohl der Prozess nicht "schläft".

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var hThread : Thandle;
    ThreadID : Cardinal;
    wf : DWORD;
begin
  Thread1 := TTest.Create(True);
  Thread1.FreeOnTerminate := True;
  Thread1.Resume;
  while (true) do;    <------Endlosschleife, nicht schön, aber geht. Wenn ich sie weglasse, startet der Thread sofort.
end;

sirius 29. Jan 2008 10:12

Re: Thread startet nicht sofort
 
Diese Ziele veranlasst,
Delphi-Quellcode:
Form1.Memo1.Lines.Add(IntToStr(a));
dass deinem Memo eine Message geschickt wird, es solle doch mal bitte den neuen Eintrag hinzufügen.

Ob das Memo (bzw, der Thread in dem das Memo ist) nun schläft oder endlos auf der Stelle hüpft kommt aufs gleiche raus. Es kommt einfach nicht zum neu zeichnen. Dazu muss es erstmal aus der aktuellen Messagebearbeitung (au sder aktuellen Funktion etc.) raus.

SirThornberry 29. Jan 2008 10:21

Re: Thread startet nicht sofort
 
Setzte einfach mal Haltepunkte (im Thread und im hauptprogramm) und du wirst sehen das beides läuft.

Aber wie die anderen bereits erwähnt haben solltest du nicht vom Thread aus auf VCL Elemente zugreifen. Ansonsten wirst du früh oder später Fehler bekommen wie "canvas does not allow drawing" oder ein Control malt sich einfach nicht mehr neu.

Zudem sollte dir bewusst sein das die Grafische Ausgabe zum hauptthread gehört. Und während dieser in einer Endlosschleife hängt oder schläft kann er nicht die Oberfläche neu zeichnen (er kenn eben immer nur einwas)

wicht 29. Jan 2008 10:23

Re: Thread startet nicht sofort
 
Delphi-Quellcode:
class TTest = class(TThread)
public
  a: integer;
  [...]
end;

implementation

procedure TTest.Execute;
begin
  try
    a := 0;
    while (a < 100) do
    begin
      inc(a);
      synchronize(machsFit);
      sleep(50);
    end;
  except
    on e: exception do begin
    end;
  end;
end;

procedure TTest.machsFit;
begin
  form1.memo1.lines.add(inttostr(a));
end;

procedure TForm1.Button1Click(Sender: TObject);
var wf : DWORD;
begin
  Thread1 := TTest.Create(True);
  Thread1.FreeOnTerminate := True;
  Thread1.Resume;
end;
So (ungefähr, ungetestet) müsste es ordentlich sein. Wenn du in deinem Test unbedingt ein Sleep möchtest, erstelle im Thread einfach eine Datei, drück den Button und guck schnell nach (innerhalb der 5 Sleep Sekunden) ob die Datei da ist...

himitsu 29. Jan 2008 10:25

Re: Thread startet nicht sofort
 
einige Thread-Erstellungsfunktionen von Delphi starten wirklich nicht gleich.

füge mal ein Sleep(0); nach Thread1.Resume; ein ... mit etwas "Glück" hilft das schon.

aber die Threadsaveangelegenheit bezüglich der VCL solltest du dennoch beheben.
und wozu einen anderen Thraed, wenn du den Hauptthread schlafen legst (anhälst)?

> Slepp und die Endlosschleife unterbrechen de Ausführung des Hauptthreads (legen diesen also sozusagen schlafen)

zweitakt 29. Jan 2008 11:40

Re: Thread startet nicht sofort
 
Hallo,

danke für die zahlreichen Antworten. Da muss ich mir wohl ein anderes Programmdesign ausdenken.

zweitakt

generic 29. Jan 2008 14:00

Re: Thread startet nicht sofort
 
Delphi-Quellcode:
while (true) do;
ist wie deine sleep idee...
der vcl prozess kann nicht das fenster neu malen.
du siehst deine änderungen nicht.

Delphi-Quellcode:
while (true) do
  application.processmessages;
würde deine änderungen zwar anzeigen, aber gut ist das so nicht.
dein multithreadproblem bleibt.


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