Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Mehr als ein laufendes TThread-Objekt führt zum Einfrieren (https://www.delphipraxis.net/126057-mehr-als-ein-laufendes-tthread-objekt-fuehrt-zum-einfrieren.html)

christian_r 17. Dez 2008 01:59


Mehr als ein laufendes TThread-Objekt führt zum Einfrieren
 
Seit langer Zeit mal wieder ... Hallo, guten Morgen.

Ich probiere mich gerade das erste Mal an Threads aus. Hier der Code für ein kleines Test-Programm.

Delphi-Quellcode:
unit unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Buttons;

type
  // Counter-ThreadObjekt
  TThreadCounter = class( TThread )
   private
    threadLabel : TLabel;
    count      : Integer;
   protected
    procedure  Show
                (  );
    procedure  Execute
                (  );
                override;
  end;

  TForm1 = class( TForm )
    Button1      : TButton;
    Button2      : TButton;
    Label1       : TLabel;
    Label2       : TLabel;
    procedure   Button1Click
                 ( Sender : TObject );
    procedure   Button2Click
                 ( Sender : TObject );
   private
    counter1     : TThreadCounter;
    statCounter1 : Boolean;
    counter2     : TThreadCounter;
    statCounter2 : Boolean;
    procedure   createThreadCounter
                 ( var pThreadCounter : TThreadCounter; var pStatCounter : Boolean; pThreadLabel : TLabel );
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// Counter aktualisieren
procedure TThreadCounter.Show
          (  );
begin
  Self.threadLabel.Caption := IntToStr( Self.count );
end;

// Thread verarbeiten
procedure TThreadCounter.Execute
          (  );
begin
  Self.count := 0;
  while True do
  begin
    Synchronize( Self.Show(  ) );
    Inc( Self.count );
    if Self.terminated then
      Break;
  end;
end;

// Thread erstellen
procedure TForm1.createThreadCounter
          ( var pThreadCounter : TThreadCounter; var pStatCounter : Boolean; pThreadLabel : TLabel );
begin
  pStatCounter := not pStatCounter;
  if pStatCounter then
  begin
    pThreadCounter                := TThreadCounter.Create( False );
    pThreadCounter.FreeOnTerminate := True;
    pThreadCounter.Priority       := tpNormal;
    pThreadCounter.ThreadLabel    := pThreadLabel;
  end
  else
    pThreadCounter.Terminate(  );
end;

// Start des Counters durch Benutzer
procedure TForm1.Button1Click
          ( Sender : TObject );
begin
  Self.createThreadCounter( Self.counter1, Self.statCounter1, Self.label1 );
end;

procedure TForm1.Button2Click
          ( Sender : TObject );
begin
  Self.createThreadCounter( Self.counter2, Self.statCounter2, Self.label2 );
end;

end.
Aufgabe:

Ich habe zwei Buttons und zwei Label. Klicke ich auf Button1 wird der Counter in Label1 aktualisiert. Nochmaliges klicken stoppt den Counter und beim wiederholten Klick beginnt er von vorn. Klappt. Das selbe gilt für Button2.

Leider kann ich nur einen Counter starten und diesen muss ich stoppen, bevor ich den zweiten Counter aktiviere. Denn stoppe ich den ersten Counter nicht, friert beim Start des zweiten das Programm ein.

Wo liegt die Ursache? Kann ich keine zwei "identische" Instanzen einer TThread-Klasse gleichzeitig laufen lassen? (In meinen Augen völliger Quatsch) Für mich absolutes Neuland.

Danke für Eure Hilfe im Voraus.

christian_r 17. Dez 2008 05:02

Re: Mehr als ein laufendes TThread-Objekt führt zum Einfrier
 
Korrektur:

Aber das war auch nicht vorherzusehen. Wenn ich das compilierte Programm ausführe, dann läuft es wie geplant. Weiß jemand, warum mein Delphi 7 ES rummuckt? Wenn ich das Programm im Einzelschritt ablaufen lasse, dann sehe ich, dass es korrekt ausgeführt wird. Hat D7 evtl. Probleme mit der korrekten Echtzeitverarbeitung der Prozesse? Eigentlich sollten diese wie gehabt unabhängig vom Betriebssystem verwaltet werden.

alzaimar 17. Dez 2008 06:07

Re: Mehr als ein laufendes TThread-Objekt führt zum Einfrier
 
1. Bei Deiner Formatierung bekommt man Augenkrebs. :freak: Halte dich doch lieber an den Standard (also Nix ändern). So ist das eine Zumutung. ;-)
2. Beim Debuggen von Threads, die dann den Hauptthread via Synchronize aufrufen, kommt der Debugger durcheinander.

christian_r 17. Dez 2008 06:31

Re: Mehr als ein laufendes TThread-Objekt führt zum Einfrier
 
Hast Du bitte eine Empfehlung zur Abhilfe? Ich will in Zukunft nicht jedesmal compilen und dann das Programm von Platte starten. Dann geht mir ja sonst ein großer Teil der Debugging-Funktionen verloren.

(An die Formatierung habe ich mich gewöhnt, daher ist sie für mich sicher genausogut lesbar wie für Dich die Std.Formatierung. Bei mir ist es umgedreht ebenso schwierig, auf Dauer die Std.Formatierung zu lesen. Aber ich werde bei den Posts versuchen an die Mehrheit im Forum zu denken.)


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