Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Thread beenden (https://www.delphipraxis.net/192000-thread-beenden.html)

Walter Landwehr 12. Mär 2017 16:46

Thread beenden
 
Hallo, Ich weiß es ist schon vieles über Thread beenden geschrieben worden aber das richtige habe ich noch nicht gefunden.

Also ich erzeuge einen Thread so.
Delphi-Quellcode:
public
  { Public-Deklarationen }
    calSyncThread: TNxSyncThread;

  procedure ThreadErzeugen(doResume: Boolean=true);
  procedure Threadbeenden;  

implementation
 
procedure TdmMain.ThreadErzeugen(doResume: Boolean=true);
begin
  if CalSyncThread = nil then begin
    calSyncThread := TNxSyncThread.Create (True);
    calSyncThread.Server := ibconMain.Server;
    calSyncThread.Path := ibconMain.Path;
    calSyncThread.LogViewEnabled := False; // für Debug auf True stellen
    calSyncThread.Protocol := ibconMain.Protocol;
    calSyncThread.StartWork;
    calSyncThread.OnTerminate := TerminateCalSynThread;
    calSyncThread.FreeOnTerminate := False; // 11.03.2017 WL
  end;
  if doResume then
    calSyncThread.Resume;
end;
und will ihn so beenden:

Delphi-Quellcode:

procedure TdmMain.Threadbeenden;
begin if CalSyncThread = nil then Exit;
  if CalSyncThread.Worker <> nil then begin
    try
      CalSyncThread.Worker.stopped := true;
      CalSyncThread.Terminate;
      while CalSyncThread.running do begin ---------> An dieser Stelle kommt ab und zu eine Schutzverletzung aber nicht immer.
        Application.ProcessMessages;
        Sleep(0);
      end;
      CalSyncThread.Worker.StoreRefrehToken;
      CalSyncThread.Worker.NxHelper.con.Connected := false;
      // FreeAndNil(CalSyncThread);
    except;
    end;
  end;
  calSyncThread.suspend;
Wer weiß wie ich den Thread sauber beende.

himitsu 12. Mär 2017 17:11

AW: Thread beenden
 
Was ist "Runnig"?


Zum "Suspend":
Threads darf man niemals "extern" anhalten, nur der Tread kann das selber machen, da nur er sicherstellen kann, dass es nicht an einer "ungünstigen" Stelle passiert.
Es wäre z.B. echt blöd, wenn man einen Thread anhält, während er gerade Speicher beim Speichermanager anfordert/freigibt, und dabei das ganze Programm lahmlegt, weil dort eine CriticalSection gesperrt bleibt.

Und ein Thread der einmal beendet wurde (Terminated), kann nicht wieder fortgesetzt neu gestartet werden.
Also ist es eh sinnlos, dass dort FreeAndNil durch Suspend ersetzt wurde, da Resume nichts neu starten kann, was bereits beendet wurde.

Walter Landwehr 12. Mär 2017 17:38

AW: Thread beenden
 
running ist ein Boolscher Wert True oder False.

Wird abgefragt ob der Thread noch läuft oder beendet ist.

himitsu 12. Mär 2017 18:03

AW: Thread beenden
 
Zitat:

Delphi-Quellcode:
while CalSyncThread.running do begin ---------> An dieser Stelle kommt ab und zu eine Schutzverletzung aber nicht immer.

War das vor oder nach?
[edit] vor der Änderung und nicht vor der Zeile :zwinker:

Zitat:

Delphi-Quellcode:
calSyncThread.FreeOnTerminate := False; // 11.03.2017 WL

Davor ist klar, wenn der Thread sich inzwischen schon freigegeben hat. :stupid:

Bei FreeOnTerminate=True darf man nie wieder von außerhalb auf das Threadobjekt zugreifen, außer im OnTerminate oder im Thread.

Mavarik 12. Mär 2017 21:56

AW: Thread beenden
 
Ohne die Execute zu sehen, ist es schwierig dazu etwas zu sagen...

Mavarik


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