Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Thread abschießen bei Programmende? (https://www.delphipraxis.net/172271-thread-abschiessen-bei-programmende.html)

HJay 21. Dez 2012 16:04

Thread abschießen bei Programmende?
 
Ich starte einige Threads, um über Indy idHTTP parallel Daten zu laden.

Wenn der Nutzer nun das Programm abbricht, bevor diese Threads fertig sind, dann würde ich diese Threads gerne korrekt beenden. Kann man das machen?

Die Threads haben keine Loop oder so sondern führen als einzigen längeren Befehl ein TidHTTP.Post oder .Get aus, das eben solange dauert.

Gibt es dazu eine geradlinige Lösung?

sx2008 21. Dez 2012 17:21

AW: Thread abschießen bei Programmende?
 
Um dem Thread zu signalisieren, dass er aufhören soll rufst du die Methode
Delphi-Quellcode:
Terminate
auf.
Innerhalb des Threads kann man sich in dem Event OnWork einklinken:
Delphi-Quellcode:
type
  TDownloadThread = class(TThread)
  private
    FIdHTTP: TIdHTTP;
    procedure OnWorkHandler(ASender: TObject; AWorkMode: TWorkMode;
      AWorkCount: Integer);
  public
    constructor Create(CreateSuspended: Boolean);
    property Cancel: boolean read FCancel write FCancel;
  end;

constructor TDownloadThread.Create(CreateSuspended: Boolean);
begin
  inherited Create(CreateSuspended);
  FIdHTTP := TIdHTTP.Create(nil);
  FIdHTTP.OnWork := OnWorkHandler;
end;

procedure TDownloadThread.OnWorkHandler(ASender: TObject; AWorkMode: TWorkMode;
  AWorkCount: Integer);
begin
  if Terminated then
  begin
    Abort;
    // oder alternativ mit Gewalt die Verbindung kappen
    FIdHTTP.Disconnect;
  end;
end;

Wishmaster 22. Dez 2012 10:47

AW: Thread abschießen bei Programmende?
 
hi.

try it this way

Delphi-Quellcode:

var ThreadID   : Cardinal = 0;


procedure Destroy_Thread(var Thread : TThread);
var
  ForceTerminate : Boolean;
begin
 if not Assigned(Thread) then
  exit;

 if not Thread.Suspended then
  ForceTerminate := True
 else
  ForceTerminate := False;

  Thread.Terminate;
//  Thread.Resume; //deprecated
  Thread.WaitFor;                      
 if ForceTerminate then
  TerminateThread(Thread.Handle, ThreadID);
  FreeAndNil(Thread);
end;

Furtbichler 22. Dez 2012 13:49

AW: Thread abschießen bei Programmende?
 
WaitFor waits for the thread. He wants to avoid it.
Also, this
Delphi-Quellcode:
if not Thread.Suspended then
  ForceTerminate := True
else
 ForceTerminate := False;
can be shortened to

Delphi-Quellcode:
ForceTerminate := Not Thread.Suspended;

Zacherl 22. Dez 2012 16:17

AW: Thread abschießen bei Programmende?
 
Wo ich hier grade den Check auf Suspended sehe:
Bitte nie mit Suspend() arbeiten, wenn es sich in irgendeiner Weise verhindern lässt oder man genau weiß, was man tut. MSDN-Library durchsuchenWaitForSingleObject ist hier eine weitaus bessere Lösung.

Ich weiß nicht, ob dieses Problem mitlerweile behoben ist, aber in einigen Delphi Versionen war ein Szenario möglich, in dem der Thread grade Speicher durch den Memory Manager (direkt oder indirekt) angefordert bzw. freigegeben hat, als er suspendiert wurde. Der Memory Manager hatte vorher eine Critical Section oder Ähnliches betreten und durch den Suspend nicht mehr verlassen. Dadurch führte dann jede folgende Speicheralloziierung im Hauptthread sofort zu einem Deadlock.

HJay 27. Dez 2012 13:03

AW: Thread abschießen bei Programmende?
 
Zitat:

Zitat von sx2008 (Beitrag 1196434)
Innerhalb des Threads kann man sich in dem Event OnWork einklinken:

Danke für diesen Tipp! Genau das suchte ich. Hat tadellos geklappt!


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