Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - Thread Execute wird nicht ausgeführt wenn constructor
whitef - Fr 24.08.12 18:07
Titel: Thread Execute wird nicht ausgeführt wenn constructor
hi,
ich habe ein Thread in meinem Projekt eingebaut.
Dieses mal wollte ich aber ein paar Werte von Beginn von meiner Form an dem Thread zukommen lassen, demnach mit
constructor Create.
Leider kommt es mir nun so vor dass
constructor TMyThread.Create zwar ausgeführt wird, aber nicht mehr
procedure TMyThread.Execute;.
Ist das normal?
Falls nicht, hier mein Projekt:
Unit meiner Form (verkürzt):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| ...
implementation
uses UnitMyThread;
...
procedure TForm1.btSaveClick(Sender: TObject); var i: Integer; TargetDir, datei0, datei1, dateien: String; Thread: TMyThread; begin .... for i := 0 to (StrToInt(dateien) - 1) do begin ... datei0 := Form1.lblPfadSource.Caption + Form1.FileListBox.Items[i]; datei1 := TargetDir + Form1.FileListBox.Items[i];
Thread := TMyThread.Create(datei0, datei1); end; end; |
Unit des Threads (komplett):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41:
| unit UnitMyThread;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, JPEG;
type TMyThread = class(TThread)
protected datei00 : String; datei11 : String;
procedure Execute; override;
Public constructor Create( datei0:String; datei1:String ); Private
end;
implementation
constructor TMyThread.Create( datei0:String; datei1:String ); Begin inherited Create(true); datei00 := datei0; datei11 := datei1; showmessage('cre: ' + datei00); FreeOnTerminate:=True; End;
procedure TMyThread.Execute; begin showmessage('exe: ' + datei00); CopyFile(PChar(datei00), PChar(datei11), True); end;
end. |
jfheins - Fr 24.08.12 18:18
Also erstmal ist ein showmessage in dem Thread eine eher schlechte Idee.
Zum eigentlichen Problem:inherited Create(true);
Der Parameter des originalen Konstruktors heißt "CreateSuspended" - nur so zum denken :P
whitef - Fr 24.08.12 18:46
Das mit "showmessage" hab ich schonmal gesagt bekommen, dass das nix in einem thread zu suchen hat; ist ja nur testweise drin.
Nur leider kann ich mit dem Rest was du geschrieben hast, nichts anfangen - ich kann mir ja nichts ausdenken...
Muss ich den originalen Parameter nehmen? Kann ich dann weitere Parameter hinzufügen? Falls nein, wie übernehme ich dann weitere Parameter in mein Thread...
Die Frage ist also noch offen
Sinspin - Fr 24.08.12 21:01
Was bezweckst Du mit inherited Create(true);? Wenn Du mal in die Hilfe schaust was Du da mit true anstellst bist Du, denke ich, ein ganzes Stück schlauer.
Das da inherited ... aufgerufen werden muss sollte außer frage stehen.
Also, was bedeutet der Parameter "CreateSuspended" den Du da mit true angibst?
Dein Quelltext ist erhlich gesagt nicht sonderlich glücklich formatiert *Arme hochreiß, wegrenn*. Tschuldigung.
Zudem nochmal: Jegliche Aufrufe von irgendwelchen Dialogen, Formularen oder Zugriffe auf Formulare haben in einem Thread nichts zu suchen. Das da nichts angezeigt wird ist noch der glückliche Verlauf. Damit kannst Du auch Dein Programm abschießen.
Zu diesem Punkt auch Hilfe lesen: Procedure Synchronize.
whitef - Fr 24.08.12 22:24
Für alle Suchenden, die nicht in der Hilfe schauen möchten und sich diese Zeit bei dieser Hitze sparen möchten:
Delphi-Quelltext
1:
| inherited Create(CreateSuspended(FALSE)); |
...bewirkt den weiteren Ablauf des Threads, demnach wird automatisch die prozedur
TMyThread.Execute angestoßen.
*ungetestet
Delphi-Quelltext
1:
| inherited Create(CreateSuspended(TRUE)); |
bewirkt den temporären Stop des Threads, demnach müsste man in der selben prozedure folgendes hinzufügen, damit die prozedur
TMyThread.Execute angestoßen wird "
Thread.Resume".
*ungetestet
Unit des Threads (komplett):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41:
| unit UnitMyThread;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, JPEG;
type TMyThread = class(TThread)
protected datei00 : String; datei11 : String;
procedure Execute; override;
Public constructor Create( datei0:String; datei1:String ); Private
end;
implementation
constructor TMyThread.Create( datei0:String; datei1:String ); Begin inherited Create(CreateSuspended(FALSE)); datei00 := datei0; datei11 := datei1; showmessage('cre: ' + datei00); FreeOnTerminate:=True; End;
procedure TMyThread.Execute; begin showmessage('exe: ' + datei00); CopyFile(PChar(datei00), PChar(datei11), True); end;
end. |
jfheins - Fr 24.08.12 23:15
Also hast du die Hilfe bedient und etwas gelernt :)
Zur Vollständigkeit halber: das "CreateSuspended" ist eigentlich noch zuviel, es müsste
Delphi-Quelltext
1:
| inherited Create(false); |
sein. Das andere dürfte eigentlich nicht kompilieren !?
Uns in späteren Versionen von Delphi doll man nicht mehr
Thread.Resume benutzen,
sondern (falls der Thread schlafend erzeugt wird) mit
TThread.Start(); starten.
jaenicke - Sa 25.08.12 07:17
FreeOnTerminate + Resume = böse
Grund: Der Thread könnte, wenn er zu wenig zu tun hat, schon vor dem Aufruf von Resume freigegeben sein... --> Race Condition
Deshalb am besten den Thread gar nicht erst Suspended erzeugen, wenn man FreeOnTerminate nutzt.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!