this
在我的一个解决方案中
为此,我创建了一个
ObjectList
var
List: TObjectList<TMyConsumerItem>;
begin
{ Create a new List. }
List := TObjectList<TMyConsumerItem>.Create();
后来我做了这样的修改:
procedure TForm1.DoSomeJob(myListItems: TStringList);
...
for i := 1 to cThreadCount do
List.Add(TMyConsumerItem.Create(aQueue, aCounter));
点击停止按钮,我正在做这个
for i := 0 to List.Count - 1 do
begin
List.Item[i].Terminate;
end;
aCounter.Free;
aQueue.Free;
在这样做的时候,我的申请被绞死了。这是正确的方法还是我遗漏了什么?
我正在使用10.2东京
编辑1:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TMyConsumerItem = class(TThread)
private
FQueue : TThreadedQueue<TProc>;
FSignal : TCountDownEvent;
protected
procedure Execute; override;
public
constructor Create( aQueue : TThreadedQueue<TProc>; aSignal : TCountdownEvent);
end;
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure StopClick(Sender: TObject);
private
{ Private declarations }
List: TObjectList<TMyConsumerItem>;
aQueue: TThreadedQueue<TProc>;
aCounter: TCountDownEvent;
procedure DoSomeJob( myListItems : TStringList);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
SyncObjs, Generics.Collections;
{- Include TMyConsumerItem class here }
procedure TForm1.Button1Click(Sender: TObject);
var
aList : TStringList;
i : Integer;
begin
aList := TStringList.Create;
Screen.Cursor := crHourGlass;
try
for i := 1 to 20 do aList.Add(IntToStr(i));
DoSomeJob(aList);
finally
aList.Free;
Screen.Cursor := crDefault;
end;
end;
procedure TForm1.StopClick(Sender: TObject);
begin
for i := 0 to List.Count - 1 do
begin
List.Item[i].Terminate;
end;
List.Free;
aCounter.WaitFor;
aCounter.Free;
aQueue.Free;
end;
procedure TForm1.DoSomeJob(myListItems: TStringList);
const
cThreadCount = 10;
cMyQueueDepth = 100;
var
i: Integer;
function CaptureJob(const aString: string): TProc;
begin
Result :=
procedure
var
i,j : Integer;
begin
// Do some job with aString
for i := 0 to 1000000 do
j := i;
// Report status to main thread
TThread.Synchronize(nil,
procedure
begin
Memo1.Lines.Add('Job with:'+aString+' done.');
end
);
end;
end;
var
aThread : TThread;
begin
List := TObjectList<TMyConsumerItem>.Create();
List.OwnsObjects := False;
aQueue := TThreadedQueue<TProc>.Create(cMyQueueDepth);
aCounter := TCountDownEvent.Create(cThreadCount);
try
for i := 1 to cThreadCount do
List.Add(TMyConsumerItem.Create(aQueue, aCounter));
for i := 0 to myListItems.Count - 1 do
begin
aQueue.PushItem(CaptureJob(myListItems[i]));
end;
finally
end;
end;
constructor TMyConsumerItem.Create(aQueue: TThreadedQueue<TProc>; aSignal : TCountDownEvent);
begin
Inherited Create(false);
Self.FreeOnTerminate := true;
FQueue := aQueue;
FSignal := aSignal;
end;
procedure TMyConsumerItem.Execute;
var
aProc : TProc;
begin
try
repeat
FQueue.PopItem(aProc);
aProc();
until Terminated;
finally
FSignal.Signal;
end;
end;
end.