AGB  ·  Datenschutz  ·  Impressum  







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

Freigeben eines suspended Threads

Ein Thema von UliBru · begonnen am 27. Apr 2012 · letzter Beitrag vom 27. Apr 2012
Antwort Antwort
UliBru

Registriert seit: 10. Mai 2010
155 Beiträge
 
Delphi 11 Alexandria
 
#1

Freigeben eines suspended Threads

  Alt 27. Apr 2012, 10:40
Hab da mal eine Frage zu folgendem minimalen Programmcode mit einem Thread.
Hauptprogramm:
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
    myThread: TmyThread;
  end;

var
  MainForm: TForm1;

implementation
{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  myThread := TmyThread.Create(true);
  myThread.FreeOnTerminate := true;
// myThread.Start;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if (myThread <> nil) then
  begin
    if not myThread.Suspended then //Thread ist gestartet
    begin
      myThread.Terminate;
      while not myThread.Finished do
        sleep(10);
    end
    else //Thread wurde nicht gestartet
      myThread.Free;
  end;
end;
Thread:
Delphi-Quellcode:
type
  TmyThread = class(TThread)
  protected
    procedure Execute; override;
  end;

implementation


procedure TmyThread.Execute;
begin
  while not Terminated do
  begin
    Sleep(50);
  end;
end;
Es geht dabei um die Frage was korrekterweise im FormClose stehen müsste. Wenn der Thread gestartet ist, alles ok. Wenn aber nicht, dann befindet sich der Thread bei Close im suspended-Zustand. myThread.Free bring eine Exception 'Thread Error: Das Handle ist ungültig'. Ohne myThread.Free gibt es ein Memory Leakage.

Wie kann man das Leakage vermeiden, also das Objekt korrekt freigeben?
Er wollte so richtig in Delphi einsteigen. Nun steckt er ganz tief drin ...
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#2

AW: Freigeben eines suspended Threads

  Alt 27. Apr 2012, 11:19
Delphi-Quellcode:
myThread.Terminate;
if myThread.Suspended then myThread.Start;
//falls Free nicht wartet (bin mir grade nicht sicher), dann hier warten bis Thread sich beendet hat
myThread.Free;
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
UliBru

Registriert seit: 10. Mai 2010
155 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Freigeben eines suspended Threads

  Alt 27. Apr 2012, 11:48
Mmhh, die Lösung, den Thread zwangsweise im FormClose zu starten, finde ich irgendwie befremdlich. Wieso wird das Objekt mit Free nicht freigegeben wie jedes andere auch?
Er wollte so richtig in Delphi einsteigen. Nun steckt er ganz tief drin ...
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#4

AW: Freigeben eines suspended Threads

  Alt 27. Apr 2012, 11:53
Wundert mich ehrlich gesagt auch, dass das Handle angeblich invalid sein soll. Die Klasse erstellt ja den Thread ganz normal per CreateThread() / BeginThread(). Auch wenn er anfangs suspended ist, darf das Handle nicht invalid sein, sonst könnte man den Thread ja überhaupt nicht mehr resumen.

Ah, lass mal das FreeOnTerminate auf false. Ich vermute hier wird irgendwie 2x versucht den Thread zu terminieren und beim 2. Versuch ist dann das Handle ungültig.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)

Geändert von Zacherl (27. Apr 2012 um 11:55 Uhr)
  Mit Zitat antworten Zitat
UliBru

Registriert seit: 10. Mai 2010
155 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Freigeben eines suspended Threads

  Alt 27. Apr 2012, 11:58
Yep, bin da auch eben dahintergekommen. Also es klappt sauber mit
Delphi-Quellcode:
  if (myThread <> nil) then
  begin
    if not myThread.Suspended then
    begin
      myThread.Terminate;
      while not myThread.Finished do
        sleep(10);
    end
    else
    begin
      myThread.FreeOnTerminate := false; // <-------- hinzugefügt
      myThread.Free;
    end;
  end;
Danke.
Er wollte so richtig in Delphi einsteigen. Nun steckt er ganz tief drin ...
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#6

AW: Freigeben eines suspended Threads

  Alt 27. Apr 2012, 12:10
Du solltest dich entscheiden, wer hier die Kontrolle hat.
- entweder du, dann FreeOnTerminate immer auf false und manuelles Free
- oder der Thread, dann FreeOnTerminate true und niemals Free
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
UliBru

Registriert seit: 10. Mai 2010
155 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Freigeben eines suspended Threads

  Alt 27. Apr 2012, 12:38
Du solltest dich entscheiden, wer hier die Kontrolle hat.
- entweder du, dann FreeOnTerminate immer auf false und manuelles Free
- oder der Thread, dann FreeOnTerminate true und niemals Free
Himitsu,

einfach danke. Mir fällt es wie Schuppen von den Haaren ...
Die meisten Beuspiele sind immer mit FreeOnTerminate := true; und so bin ich da ebenfalls reingestolpert.
Aber die DH sagt auch
Zitat:
If you want to communicate with the thread or otherwise interact with it, including telling it when to terminate, FreeOnTerminate should never be used. Calling Free on a TThread will set Terminated := True and then block until the thread terminates.
Und so löst sich alles einfach auf mit:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  myThread := TmyThread.Create(true);
  //... evtl. weitere Initialisierung, daher createsuspended
  myThread.Start;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  myThread.Free;
end;
Das klappt egal ob der Thread gestartet ist oder nicht.
Er wollte so richtig in Delphi einsteigen. Nun steckt er ganz tief drin ...
  Mit Zitat antworten Zitat
Antwort Antwort


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 10:25 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