Ich habe in einem D2007 Programm sinngemäß folgenden Code:
Delphi-Quellcode:
TmyThread = class(TThread)
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean);
destructor Destroy; override;
end;
constructor TmyThread.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
end;
destructor TmyThread.Destroy;
begin
inherited;
end;
procedure TmyThread.Execute;
begin
while not Terminated do begin
// mach irgend etwas, berechne
self.Suspend;
end;
end;
.
.
.
procedure TfrmMain.FormCreate(Sender: TObject);
begin
myThread := TmyThread.Create(True);
myThread.FreeOnTerminate := True;
myThread.Resume; // Starte Thread und laufe einmal durch
end;
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
myThread.Terminate;
if myThread.Suspended then begin
myThread.Resume;
end;
// Was kann man hier einbauen um zu prüfen, ob der Thread beendet und zerstört ist
end;
Also der Thread läuft beim Starten einmal durch und legt sich dann selbst schlafen. Unter verschiedenen Umständen in meinem Programm wird der Thread ab und zu mal wieder aufgeweckt. Das funktioniert auch alles wunderbar und ohne Probleme.
Mein Problem ist allerdings, dass ab und zu beim Beenden vom Programm ein Runtime Error 216 kommt. Ich habe dann herausgefunden dass es am Thread liegt, bzw. dass er wohl noch nicht beendet und zerstört ist, das Hauptformular aber dann schon. Wenn ich das Programm über die
IDE starte, dann kommt der Fehler fast gar nicht, wenn ich die EXE außerhalb der
IDE starte, dann kommt der Fehler ziemlich oft.
Ich habe auch schon folgendes probiert:
Delphi-Quellcode:
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
myThread.Terminate;
if myThread.Suspended then begin
myThread.Resume;
end;
myThread.WaitFor; // <----- neu
end;
aber dann gibts ein Fehler bei WaitFor, dass die Thread ID nicht stimmt (oder so ähnlich).
Wenn ich folgendes mache:
Delphi-Quellcode:
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
myThread.Terminate;
if myThread.Suspended then begin
myThread.Resume;
end;
sleep(50); // kurze Pause
end;
dann gibt es nie einen Fehler, das gefällt mir aber nicht, einfach eine Pause da rein zu hauen.
Folgendes bringt mich auch nicht weiter:
Delphi-Quellcode:
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
myThread.Terminate;
if myThread.Suspended then begin
myThread.Resume;
end;
while myThread <> nil do begin // <----- neu
sleep(50);
Application.ProcessMessages;
end;
end;
Das Problem dabei ist, dass myThread nach dem beenden und zerstören immer noch <> nil ist. Ich habe auch geprüft, dass beim Aufruf von Resume das Execute des thread verlassen wird und Destroy des Thread wird auch durchlaufen.
Habt Ihr eine Idee, was ich tun kann, wenn FreeOnTerminate := True und ich den Thread dann selbst terminiere, ich aber noch prüfen will, ob er wirklich beendet ist.
Danke
Sven