Einzelnen Beitrag anzeigen

christian_r
(Gast)

n/a Beiträge
 
#1

Mehr als ein laufendes TThread-Objekt führt zum Einfrieren

  Alt 17. Dez 2008, 02:59
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.
  Mit Zitat antworten Zitat