我已经使用 Delphi 有一段时间了,现在正尝试在我的代码中实现多线程,要求如下:
每次只能运行 2 个线程。
其他任务应在队列中等待,并在线程可用时执行。
我尝试使用TParallel.For
来实现这一点,但无法实现所需的行为。这是我的示例代码:
type
TMyRecord = record
msg: String;
sleep: Integer;
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
var
record1, record2, record3, record4, record5: TMyRecord;
MyList: TList<TMyRecord>;
begin
// Initialize records
record1.msg := 'Item1';
record1.sleep := 10;
record2.msg := 'Item2';
record2.sleep := 10;
record3.msg := 'Item3';
record3.sleep := 3000;
record4.msg := 'Item4';
record4.sleep := 3000;
record5.msg := 'Item5';
record5.sleep := 100;
MyList := TList<TMyRecord>.Create;
try
// Add records to the list
MyList.Add(record1);
MyList.Add(record2);
MyList.Add(record3);
MyList.Add(record4);
MyList.Add(record5);
// Use TParallel.For
TParallel.For(0, MyList.Count - 1,
procedure (i: Integer)
var
ListItem: TMyRecord;
begin
ListItem := MyList[i];
TThread.Synchronize(nil,
procedure
begin
Memo1.Lines.Add(ListItem.msg);
end);
Sleep(ListItem.sleep);
end);
finally
MyList.Free;
end;
end;
我也尝试使用TTask.Run
和ThreadPool
,但无法实现所需的行为。更新 - 这是我尝试使用 Threadpool 执行的操作
procedure TForm2.Button1Click(Sender: TObject);
var
record1, record2, record3, record4, record5: TMyRecord;
MyList: TList<TMyRecord>;
ThreadPool: TThreadPool;
begin
// Initialize records
record1.msg := 'Item1';
record1.sleep := 10;
record2.msg := 'Item2';
record2.sleep := 10;
record3.msg := 'Item3';
record3.sleep := 3000;
record4.msg := 'Item4';
record4.sleep := 3000;
record5.msg := 'Item5';
record5.sleep := 100;
MyList := TList<TMyRecord>.Create;
try
// Add records to the list
MyList.Add(record1);
MyList.Add(record2);
MyList.Add(record3);
MyList.Add(record4);
MyList.Add(record5);
ThreadPool := TThreadPool.Create;
ThreadPool.SetMaxWorkerThreads(2);
// Iterate through the list and queue each work item with a copy of the record
for var i := 0 to MyList.Count - 1 do
begin
var ListItem := MyList[i];
ThreadPool.QueueWorkItem(
procedure
var
LocalItem: TMyRecord;
begin
LocalItem := ListItem;
TThread.Queue(nil,
procedure
begin
Memo1.Lines.Add(LocalItem.msg);
Sleep(LocalItem.sleep); // Simulate the delay
end);
end);
end;
finally
MyList.Free;
end;
end;
此代码有问题-
- 它仅打印“item5”5次。
- 等待时间(睡眠)不起作用。
我该如何修改此代码以将同时运行的线程数限制为 2?并在线程可用时将其他任务排队执行?