unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.SyncObjs,
System.Threading;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
tasks: array [0 .. 2] of Itask;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
tasks[0].Start;
tasks[1].Start;
tasks[2].Start;
end;
procedure TForm1.Button2Click(Sender: TObject);
var i:integer;
begin
tasks[0].Cancel;
tasks[1].Cancel;
tasks[2].Cancel;
{try
TTask.WaitForAll(tasks) ; //这个不行,要exception
except
end;}
for I := 0 to 2 do begin
if tasks[i].Status<>TTaskStatus.Completed then begin //主线程有访问TTask的Status属性,线程内部也会访问它,但是不会引发冲突,因为查看源代码发现它有[Volatile]属性
application.ProcessMessages;
sleep(10);
continue;
end;
end;
Memo1.Lines.Add('All done.');
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
tasks[0] := ttask.Create(
procedure()
begin
while ttask.CurrentTask.Status <> TTaskStatus.Canceled do
begin
sleep(10);
TThread.Synchronize(nil,
procedure()
begin
Form1.Memo1.Lines.Add('Task 1 ...');
end);
end;
TThread.Synchronize(nil,
procedure()
begin
Form1.Memo1.Lines.Add('Task 1 end');
end);
end);
tasks[1] := ttask.Create(
procedure()
begin
while ttask.CurrentTask.Status <> TTaskStatus.Canceled do
begin
sleep(15);
TThread.Synchronize(nil,
procedure()
begin
Form1.Memo1.Lines.Add('Task 2 ...');
end);
end;
TThread.Synchronize(nil,
procedure()
begin
Form1.Memo1.Lines.Add('Task 2 end');
end);
end);
tasks[2] := ttask.Create(
procedure()
begin
while ttask.CurrentTask.Status <> TTaskStatus.Canceled do
begin
sleep(12);
TThread.Synchronize(nil,
procedure()
begin
Form1.Memo1.Lines.Add('Task 3 ...');
end);
end;
TThread.Synchronize(nil,
procedure()
begin
Form1.Memo1.Lines.Add('Task 3 end');
end);
end);
end;
end.
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.SyncObjs,
System.Threading;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
tasks: array [0 .. 2] of Itask;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
tasks[0].Start;
tasks[1].Start;
tasks[2].Start;
end;
procedure TForm1.Button2Click(Sender: TObject);
var i:integer;
begin
tasks[0].Cancel;
tasks[1].Cancel;
tasks[2].Cancel;
{try
TTask.WaitForAll(tasks) ; //这个不行,要exception
except
end;}
for I := 0 to 2 do begin
if tasks[i].Status<>TTaskStatus.Completed then begin //主线程有访问TTask的Status属性,线程内部也会访问它,但是不会引发冲突,因为查看源代码发现它有[Volatile]属性
application.ProcessMessages;
sleep(10);
continue;
end;
end;
Memo1.Lines.Add('All done.');
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
tasks[0] := ttask.Create(
procedure()
begin
while ttask.CurrentTask.Status <> TTaskStatus.Canceled do
begin
sleep(10);
TThread.Synchronize(nil,
procedure()
begin
Form1.Memo1.Lines.Add('Task 1 ...');
end);
end;
TThread.Synchronize(nil,
procedure()
begin
Form1.Memo1.Lines.Add('Task 1 end');
end);
end);
tasks[1] := ttask.Create(
procedure()
begin
while ttask.CurrentTask.Status <> TTaskStatus.Canceled do
begin
sleep(15);
TThread.Synchronize(nil,
procedure()
begin
Form1.Memo1.Lines.Add('Task 2 ...');
end);
end;
TThread.Synchronize(nil,
procedure()
begin
Form1.Memo1.Lines.Add('Task 2 end');
end);
end);
tasks[2] := ttask.Create(
procedure()
begin
while ttask.CurrentTask.Status <> TTaskStatus.Canceled do
begin
sleep(12);
TThread.Synchronize(nil,
procedure()
begin
Form1.Memo1.Lines.Add('Task 3 ...');
end);
end;
TThread.Synchronize(nil,
procedure()
begin
Form1.Memo1.Lines.Add('Task 3 end');
end);
end);
end;
end.