Hallo zusammen,
ich beschäftige mich vermutlich mit mäßigem Erfolg mit Threads und habe dazu ein Beispiel hier aus dem Forum ausgewählt, dass unlängst hier diskutiert wurde.
https://www.delphipraxis.net/210313-...d-starten.html
Ich habe also das von #Sinspin gepostete Beispiel für mich zum Verständnis ausgewählt.
Da wird also ein Haupt-Thread erzeugt, in dem eine Schleife bis 100 zählt und diese dann an ein Counter.Label sendet.
Als weiterer Thread wird ein Activityindicator erzeugt. Beide Threads laufen parallel.
Nun wollte ich das Beispiel erweitern und einen weiteren Hintergrund-Thread hinzufügen und erhalte folgenden Effekt:
Der 2. Thread mit einem weiteren Activityindicator und einer Schleife, die bis 70 zählt wird sofort ausgeführt (zählt bis 70 und 2. Activityindicator wird angezeigt).
Ebenfalls parallel wird der 1. Activityindicator ausgeführt.
Erst wenn die 70-ger-Schleife (2.Thread) abgearbeitet wurde startet die Schleife bis 100 (Haupt-Thread) und beide Activityindicatoren werden parallel angezeigt.
Ist das so richtig?
Wie muß man ein Konstrukt mit einem Haupt-Thread und zwei weiteren Threads bauen? Ich bin da so völlig unbedarft und taste mich an die ominösen Threads erst heran.
Die hier oft diskutierten Beispiele sind mir oft zu kompliziert um nur das Wesen der Threads zu begreifen und natürlich auch deren Synchronisation.
Nun noch mein Erweiterungs-Konstruckt auf 2 Threads neben dem Haupt-Thread:
Delphi-Quellcode:
unit Unit1;
interface
uses
Winapi.Windows,
Winapi.Messages, System.SysUtils, System.Variants, System.Threading,
System.Classes,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs,
Vcl.StdCtrls,
Vcl.WinXCtrls,
Vcl.ExtCtrls;
type
TheThread =
class(TThread)
private
procedure DoIt;
public
procedure Execute;
override;
end;
type
TheThread2 =
class(TThread)
private
procedure DoIt2;
public
procedure Execute;
override;
end;
type
TForm1 =
class(TForm)
actvtyndctr1: TActivityIndicator;
CounterLabel: TLabel;
StartThreadBtn: TButton;
btnclose: TButton;
lblDoit2: TLabel;
actvtyndctr2: TActivityIndicator;
lblThread2: TLabel;
lblThread1: TLabel;
bvl1: TBevel;
lblHauptThread: TLabel;
procedure StartThreadBtnClick(Sender: TObject);
procedure btncloseClick(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TheTread1 }
procedure TheThread.DoIt;
begin
Form1.actvtyndctr1.Animate := true;
end;
procedure TheThread.Execute;
begin
Synchronize(DoIt);
end;
{ TheTread2 }
procedure TheThread2.DoIt2;
var i: int32;
begin
Form1.actvtyndctr2.Animate:= True;
for i := 0
to 70
do
begin
Form1.lblDoIt2.Caption := I.tostring;
Application.ProcessMessages;
Sleep(30);
end;
end;
procedure TheThread2.execute;
begin
inherited;
Synchronize(DoIt2);
end;
procedure TForm1.btncloseClick(Sender: TObject);
begin
Close;
end;
procedure TForm1.StartThreadBtnClick(Sender: TObject);
var
Thread: TheThread;
Thread2: TheThread2;
I: integer;
begin
try
// Thread starten
Thread := TheThread.Create(True);
Thread.FreeOnTerminate := true;
Thread.Start;
Thread2:=TheThread2.Create(True);
thread2.FreeOnTerminate:=True;
thread2.Start;
// Hauptthread Zählt bis 100 u. gibt Ergebnis aus
for I := 0
to 100
do
begin
Form1.CounterLabel.Caption := I.tostring;
Application.ProcessMessages;
Sleep(50);
end;
Form1.actvtyndctr1.Animate := false;
Form1.actvtyndctr2.Animate := false;
except
on E:
Exception do
begin
Form1.actvtyndctr1.Animate := false;
Form1.actvtyndctr2.Animate := false;
end;
end;
end;
end.
Anbei das Beispielprogramm