Einzelnen Beitrag anzeigen

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