AGB  ·  Datenschutz  ·  Impressum  







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

Thread aus Tobjectlist beenden

Ein Thema von youuu · begonnen am 27. Jun 2014 · letzter Beitrag vom 28. Jun 2014
Antwort Antwort
youuu

Registriert seit: 2. Sep 2008
Ort: Kleve
822 Beiträge
 
Delphi 2010 Professional
 
#1

Thread aus Tobjectlist beenden

  Alt 27. Jun 2014, 23:55
Hi,

im FormCloseQuery frage ich meine Objectlist ab, on moch Thread vorhanden sind und wenn ja sollen diese sofort beendet werden.

Delphi-Quellcode:
  if FThread_liste.Count <> 0 then Begin
    for i := 0 to FThread_liste.Count -1 do begin
      if Assigned((FThread_liste.Items[i] as TThread)) then
        (FThread_liste.Items[i] as TThread).Terminate;
    end;
  End;
Allerdings alufen die Threads einfach munter weiter.
Steven
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#2

AW: Thread aus Tobjectlist beenden

  Alt 28. Jun 2014, 00:11
Fragen die Threads denn regelmäßig ab, ob sie Terminated wurden? (und beenden sich dann auch!)
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
youuu

Registriert seit: 2. Sep 2008
Ort: Kleve
822 Beiträge
 
Delphi 2010 Professional
 
#3

AW: Thread aus Tobjectlist beenden

  Alt 28. Jun 2014, 00:14
Delphi-Quellcode:
while not (FThread_liste.Items[i] as TThread).Terminated do
  Delay(200);
[dcc32 Fehler] Form_Main.pas(1662): E2362 Auf protected-Symbol TThread.Terminated kann nicht zugegriffen werden

Hm
Steven
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Thread aus Tobjectlist beenden

  Alt 28. Jun 2014, 00:19
Den Code kann man auch so schreiben
Delphi-Quellcode:
// OwnsObjects sollte True sein
FThread_liste.Clear;
Delphi-Quellcode:
while not (FThread_liste.Items[i] as TThread).Terminated do
  Delay(200);
[dcc32 Fehler] Form_Main.pas(1662): E2362 Auf protected-Symbol TThread.Terminated kann nicht zugegriffen werden

Hm
Die Threads und nicht die Thread-Liste sollen ja auch das Terminated auswerten.
Der Code zeigt allerdings auch, dass du das eben nicht machst, da du augenscheinlich nicht weißt, wo und wozu man das benutzt.
Delphi-Quellcode:
procedure TMyThread.Execute;
begin
  inherited;
  while not Terminted do
  begin
    // tue was hier immer wieder ohne Unterlass, ok bis eben Terminated
  end;
end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (28. Jun 2014 um 00:29 Uhr)
  Mit Zitat antworten Zitat
youuu

Registriert seit: 2. Sep 2008
Ort: Kleve
822 Beiträge
 
Delphi 2010 Professional
 
#5

AW: Thread aus Tobjectlist beenden

  Alt 28. Jun 2014, 00:20
Sir Rufo, das versteh ich nun nicht so ganz, was hat das damit zu tun das der Thread beendet werden soll?
Oder gibt die Liste dann die Threads automatisch frei?

Edit: hab ich eben ausprobiert, thread abeit dennoch weiter.
Steven

Geändert von youuu (28. Jun 2014 um 00:23 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Thread aus Tobjectlist beenden

  Alt 28. Jun 2014, 00:27
Sir Rufo, das versteh ich nun nicht so ganz, was hat das damit zu tun das der Thread beendet werden soll?
Oder gibt die Liste dann die Threads automatisch frei?

Edit: hab ich eben ausprobiert, thread abeit dennoch weiter.
Na logisch, wenn der Thread auch nicht selber schaut, ob er aufhören soll

Eine TObjectList mit Delphi-Referenz durchsuchenTObjectList.OwnsObjects auf True verwaltet die Instanzen des Inhaltes selber und bei Clear werden alle Instanzen (in der Liste) freigegeben.

Ein Thread wird im destructor beendet (Terminate) und die Instanz verschwindet im Nirwana ...

... wenn der Thread-Code auch wirklich aufhört
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (28. Jun 2014 um 00:29 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Thread aus Tobjectlist beenden

  Alt 28. Jun 2014, 01:13
Delphi-Quellcode:
  if FThread_liste.Count <> 0 then Begin
    for i := 0 to FThread_liste.Count -1 do begin
      if Assigned((FThread_liste.Items[i] as TThread)) then
        (FThread_liste.Items[i] as TThread).Terminate;
    end;
  End;
Da der Code ja im Delphi-Referenz durchsuchenTForm.OnCloseQuery laufen soll, solltest du den wie folgt nehmen:
Delphi-Quellcode:
for i := 0 to FThread_liste.Count - 1 do
  if Assigned(FThread_list.Items[i]) and (FThread_list.Items[i] is TThread) then
    (FThread_liste.Items[i] as TThread).Terminate;
  1. Die Überprüfung if FThread_liste.Count <> 0 then ist überflüssig, denn genau das passiert auch bei for i := 0 to FThread_liste.Count - 1 do
  2. Triffst du bei FThread_liste.Items[i] as TThread auf ein Element, das nicht von TThread abgleitet wurde, dann bekommst du eine Exception um die Ohren gehauen Delphi-Referenz durchsuchenEInvalidCast. Das Assigned() drumherum hilft dir da auch nicht mehr.
Hier der Test
Delphi-Quellcode:
program dp_180889;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  {System} SysUtils, Contnrs, Classes;

type
  TTestThread = class( TThread )
  protected
    procedure Execute; override;
  end;

  { TTestThread }

procedure TTestThread.Execute;
begin
  inherited;
  while not Terminated do
    begin
      Sleep( 50 ); // immer nur ein wenig schlafen, bis eben Terminated ...
    end;
end;

{$DEFINE UNSICHER}

procedure Test;
var
  LList : TObjectList;
  LIdx : Integer;
begin
  LList := TObjectList.Create( True );
  try

    LList.Add( TTestThread.Create( False ) );
    LList.Add( nil );
    LList.Add( TObject.Create ); // Eine einfache TObject-Instanz
    LList.Add( TTestThread.Create( False ) );
{$IFDEF UNSICHER}
    write( 'UNSICHER: ' );
{$ELSE}
    write( 'SICHER: ' );
{$ENDIF}
    for LIdx := 0 to LList.Count - 1 do
      begin
        write( LIdx, '...' );
{$IFDEF UNSICHER}
        if Assigned( LList.Items[LIdx] as TThread )
{$ELSE}
        if Assigned( LList.Items[LIdx] ) and ( LList.Items[LIdx] is TThread )
{$ENDIF}
        then
          // Threads mitteilen, dass sie sich beenden sollen
          ( LList.Items[LIdx] as TThread ).Terminate;
      end;

    Writeln( 'Fertig' );

    LList.Clear; // Wenn der Befehl durch ist, dann sind auch alle Threads beendet

  finally
    LList.Free;
  end;
end;

begin
  try
    Test;
  except
    on E : Exception do
      Writeln( E.ClassName, ': ', E.Message );
  end;
  Readln;

end.
und das Resultat
Code:
UNSICHER: 0...1...2...EInvalidCast: Ungültige Typumwandlung
SICHER: 0...1...2...3...Fertig
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#8

AW: Thread aus Tobjectlist beenden

  Alt 28. Jun 2014, 09:35
Wenn Du auf 'is' abfragst, kannst Du hart casten. Das Pattern
Delphi-Quellcode:
if (foo is TBar) then
  TBar(foo)....
// Ist genauso sicher wie(aber wesentlich schneller als)
if (foo is TBar) then
  (foo as TBar)....
Zusätzlich sollte man noch darauf hinweisen (auch wenn es eigentlich selbstverständlich ist), das ein Thread in seiner Execute-Methode 'immer mal wieder' auf 'Terminated' prüfen sollte, d.h. auch in inneren Schleifen. Die 'Terminate' Methode beendet den Thread nämlich überhaupt nicht, sondern setzt nur das Flag 'Terminated' auf True.

Die Methode sollte also besser heißen: 'TerminateRequest', oder auf deutsch: 'SachDenFredErSollSichMaBeendenAberErMussDasSchonA uchMerkenNe';
  Mit Zitat antworten Zitat
youuu

Registriert seit: 2. Sep 2008
Ort: Kleve
822 Beiträge
 
Delphi 2010 Professional
 
#9

AW: Thread aus Tobjectlist beenden

  Alt 28. Jun 2014, 10:40
Ah ok, jetzt versteh ich es. Danke
Steven
  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 17:37 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