我想使用OmniThreadLibrary的默认线程池,即不创建我自己的本地线程。
我有一个方法ValidateInvoiceFile。发票文件只是一个自包含的发票对象列表。
在我的服务中调用ValidateInvoiceFile。用户1验证文件1,用户2验证文件2 - 这将在2个完全独立的呼叫中发生
例如
用户1 - 文件1 - 发票1,发票2,发票3
用户2 - 文件2 - 发票34231,发票31235
每张发票都将在自己的任务中进行验证。所以在这种情况下我会有5个任务。
我需要我的ValidateInvoiceFiles过程等待所有任务(如果已创建)完成。不是所有的任务。在很多情况下,人们希望等到所有任务都完成,但这不是这种情况。
文件1的ValidateInvoices调用对文件2的任务没有兴趣所以我不希望它等待它们
如何使用OmniThreadLibrary for Delphi
进行此操作我正在考虑OnThreadTerminated事件,但我不确定如何只关注特定调用期间添加的任务。
procedure ValidateInvoiceFile(const objInvoices: TInvoices)
begin
try
objThreadPool := CreateThreadPool('Connection pool');
objThreadPool.MaxExecuting := 2 * System.CPUCount;
nStart := 0;
nEnd := 49;
while nStart <= objInvoices.Count - 1 do
begin
for InvoiceIndex := nStart to nEnd do
begin
if InvoiceIndex > objInvoices.Count - 1 then
Break;
objInvoice := objInvoices[InvoiceIndex];
objValidationData := TValidationData.Create(FConnection, FAllInvoices, FAllInvoices[InvoiceIndex]);
//I fill objValidationData with information to be given to the task
CreateTask(
procedure(const task: IOmniTask)
var
objLocalInvoice: TInvoice;
ValidatorIndex: Integer;
objValidator: TInvValidator;
objUtilities: TUtilities;
objValidationData: TValidationData;
nLocalInvoiceIndex: Integer;
nValidatorIndex: Integer;
begin
nLocalInvoiceIndex := Task.Param['InvoiceIndex'].AsInteger;
objValidationData := TValidationData(Task.Param['objValidationData'].AsObject);
try
//Do my work here
finally
FreeAndNil(objValidationData);
end;
end
)
.SetParameter('InvoiceIndex', InvoiceIndex)
.SetParameter('objValidationData', TObject(objValidationData))
.Unobserved
.Schedule(objThreadPool);
end;
/**** This is the part I dont know how to change*****/
while objThreadPool.CountExecuting + objThreadPool.CountQueued > 0 do
Self := Self;
Inc(nStart, 50);
Inc(nEnd, 50);
end;
finally
objThreadPool := nil;
end;
end;
答案 0 :(得分:2)
类似的东西应该有用(如果我理解正确的话):
uses
OtlCommon,
OtlParallel;
GlobalParallelPool.MaxExecuting := Environment.System.Affinity.Count * 2;
procedure ValidateInvoiceFile(const objInvoices: TInvoices);
begin
Parallel.ForEach(0, objInvoices.Count - 1)
.Execute(
procedure(const invoiceIndex: integer)
begin
//validate objInvoices[invoiceIndex]
end);
end;