unit fo_ThreadListDePraxis;
interface
uses
Winapi.Windows,
Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs,
Vcl.StdCtrls, Generics.Collections,
Vcl.Samples.Spin;
type
TForm1 =
class(TForm)
laSleeptime: TLabel;
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
SpinEdit1: TSpinEdit;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject;
var Action: TCloseAction);
procedure Button2Click(Sender: TObject);
procedure SpinEdit1Change(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
TMyList =
class(TList<Integer>)
end;
TMyThread =
class(TThread)
private
FCounter, FSleepTime: Integer;
protected
procedure Execute;
override;
public
property SleepTime: Integer
read FSleepTime
write FSleepTime;
end;
var
Form1: TForm1;
MyList: TMyList;
MyThread: TMyThread;
implementation
{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject);
begin
if assigned(MyThread)
then
begin
MyThread.Terminate;
// Setzt MyThread nicht auf NIL, d.h. nächster Button2Click führt wieder in diesn Block
Button2.Caption := '
Start Thread';
end
else
begin
Button2.Caption := '
Terminate Thread';
MyThread := TMyThread.Create(true);
// Create suspended--secondProcess does not run yet.
MyThread.FreeOnTerminate := true;
// You do not need to clean up after termination.
MyThread.SleepTime := SpinEdit1.Value;
MyThread.Resume;
// Now run the thread.
end;
end;
procedure TForm1.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
MyList.Free;
MyThread.Terminate;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
MyList := TMyList.Create;
end;
procedure TForm1.SpinEdit1Change(Sender: TObject);
begin
if assigned(MyThread)
then
MyThread.SleepTime := SpinEdit1.Value;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
for i := 0
to 20
do
MyList.Add(random(200));
end;
{ TMyThread }
procedure TMyThread.Execute;
var
i: Integer;
begin
inherited;
while (true)
do
begin
if Terminated
then
exit;
inc(FCounter);
Form1.Label1.Caption := IntToStr(FCounter);
Form1.Memo1.Clear;
System.TMonitor.Enter(MyList);
// Liste gegen Zweitzugriff sperren. Muss das sein?
try
for i := 0
to MyList.Count - 1
do
begin
if Terminated
then
exit;
Form1.Memo1.Lines.Add(format('
%d: %d', [i, MyList.Items[i]]));
// Ist das zulässig?
end;
finally
System.TMonitor.exit(MyList);
// Sperrung der Liste wieder aufheben
end;
sleep(FSleepTime);
// FSleepTime oder besser SleepTime?
end;
end;
end.