【发布时间】:2015-04-03 13:20:13
【问题描述】:
我想使用 OmniThreadLibrary 的默认线程池,即不创建自己的本地线程池。
我有一个方法 ValidateInvoiceFile。发票文件只是一个独立的发票对象列表。
ValidateInvoiceFile 在我的服务中被调用。用户 1 验证文件 1,用户 2 验证文件 2 - 这将发生在 2 个完全独立的调用中
例如
用户 1 - 文件 1 - 发票 1、发票 2、发票 3
用户 2 - 文件 2 - 发票 34231、发票 31235
每张发票都将在其自己的任务中进行验证。所以在这种情况下,我将有 5 个任务。
我需要我的 ValidateInvoiceFiles 过程等到所有创建的任务都完成。不是所有的任务。在很多情况下,人们希望等到所有任务都完成后,但这里并非如此。
文件 1 的 ValidateInvoices 调用对文件 2 的任务不感兴趣,所以我不希望它等待它们
我将如何使用 Delphi 的 OmniThreadLibrary 来做到这一点
我在考虑 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;
【问题讨论】:
-
您使用的是哪个 Delphi?如果您至少使用 Delphi 2009,那么这里有一些高级抽象会对您有所帮助。
-
我使用的是 Delphi XE 5
-
我是否认为在我的情况下本地线程池不是一个好主意?可以同时验证任意数量的文件。在正常情况下,我们有大约 100 个系统实例在使用中,并且无法预测用户将要做什么!他们希望能够同时验证多个文件。我认为如果我使用本地池,我最终可能会使用太多线程
-
你不需要本地线程池。你只需要一个更好的抽象。
标签: multithreading delphi